python-injection 0.6.7__py3-none-any.whl → 0.6.8__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/_pkg.py +3 -0
- injection/_pkg.pyi +14 -2
- injection/common/tools/_type.py +16 -15
- injection/core/module.py +25 -25
- {python_injection-0.6.7.dist-info → python_injection-0.6.8.dist-info}/METADATA +14 -5
- {python_injection-0.6.7.dist-info → python_injection-0.6.8.dist-info}/RECORD +7 -7
- {python_injection-0.6.7.dist-info → python_injection-0.6.8.dist-info}/WHEEL +0 -0
injection/_pkg.py
CHANGED
|
@@ -8,6 +8,7 @@ __all__ = (
|
|
|
8
8
|
"get_lazy_instance",
|
|
9
9
|
"inject",
|
|
10
10
|
"injectable",
|
|
11
|
+
"set_constant",
|
|
11
12
|
"singleton",
|
|
12
13
|
)
|
|
13
14
|
|
|
@@ -19,3 +20,5 @@ get_lazy_instance = default_module.get_lazy_instance
|
|
|
19
20
|
inject = default_module.inject
|
|
20
21
|
injectable = default_module.injectable
|
|
21
22
|
singleton = default_module.singleton
|
|
23
|
+
|
|
24
|
+
set_constant = default_module.set_constant
|
injection/_pkg.pyi
CHANGED
|
@@ -17,6 +17,8 @@ inject = default_module.inject
|
|
|
17
17
|
injectable = default_module.injectable
|
|
18
18
|
singleton = default_module.singleton
|
|
19
19
|
|
|
20
|
+
set_constant = default_module.set_constant
|
|
21
|
+
|
|
20
22
|
@final
|
|
21
23
|
class Module:
|
|
22
24
|
"""
|
|
@@ -59,12 +61,22 @@ class Module:
|
|
|
59
61
|
singleton will be constructed. At injection time, the injected instance will
|
|
60
62
|
always be the same.
|
|
61
63
|
"""
|
|
62
|
-
def
|
|
64
|
+
def set_constant(
|
|
65
|
+
self,
|
|
66
|
+
instance: _T,
|
|
67
|
+
on: type | Iterable[type] | UnionType = ...,
|
|
68
|
+
) -> _T:
|
|
69
|
+
"""
|
|
70
|
+
Function for registering a specific instance to be injected. This is useful for
|
|
71
|
+
registering global variables. The difference with the singleton decorator is
|
|
72
|
+
that no dependencies are resolved, so the module doesn't need to be locked.
|
|
73
|
+
"""
|
|
74
|
+
def get_instance(self, cls: type[_T]) -> _T | None:
|
|
63
75
|
"""
|
|
64
76
|
Function used to retrieve an instance associated with the type passed in
|
|
65
77
|
parameter or return `None`.
|
|
66
78
|
"""
|
|
67
|
-
def get_lazy_instance(self, cls: type[_T]
|
|
79
|
+
def get_lazy_instance(self, cls: type[_T]) -> Lazy[_T | None]:
|
|
68
80
|
"""
|
|
69
81
|
Function used to retrieve an instance associated with the type passed in
|
|
70
82
|
parameter or `None`. Return a `Lazy` object. To access the instance contained
|
injection/common/tools/_type.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from collections.abc import Iterator
|
|
1
2
|
from types import NoneType, UnionType
|
|
2
|
-
from typing import
|
|
3
|
+
from typing import Annotated, Any, Union, get_args, get_origin
|
|
3
4
|
|
|
4
5
|
__all__ = ("format_type", "get_origins")
|
|
5
6
|
|
|
@@ -11,25 +12,25 @@ def format_type(cls: type | Any) -> str:
|
|
|
11
12
|
return str(cls)
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
def get_full_origin(cls: type | Any) -> type | Any:
|
|
15
|
-
try:
|
|
16
|
-
origin = cls.__origin__
|
|
17
|
-
except AttributeError:
|
|
18
|
-
return cls
|
|
19
|
-
|
|
20
|
-
return get_full_origin(origin)
|
|
21
|
-
|
|
22
|
-
|
|
23
15
|
def get_origins(*classes: type | Any) -> Iterator[type | Any]:
|
|
24
16
|
for cls in classes:
|
|
25
|
-
|
|
17
|
+
origin = get_origin(cls) or cls
|
|
18
|
+
|
|
19
|
+
if origin in (None, NoneType):
|
|
26
20
|
continue
|
|
27
21
|
|
|
28
|
-
|
|
22
|
+
arguments = get_args(cls)
|
|
23
|
+
|
|
24
|
+
if origin in (Union, UnionType):
|
|
25
|
+
yield from get_origins(*arguments)
|
|
26
|
+
|
|
27
|
+
elif origin is Annotated:
|
|
28
|
+
try:
|
|
29
|
+
annotated = arguments[0]
|
|
30
|
+
except IndexError:
|
|
31
|
+
continue
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
for argument in get_args(cls):
|
|
32
|
-
yield from get_origins(argument)
|
|
33
|
+
yield from get_origins(annotated)
|
|
33
34
|
|
|
34
35
|
else:
|
|
35
36
|
yield origin
|
injection/core/module.py
CHANGED
|
@@ -46,6 +46,7 @@ _logger = logging.getLogger(__name__)
|
|
|
46
46
|
_thread_lock = RLock()
|
|
47
47
|
|
|
48
48
|
_T = TypeVar("_T")
|
|
49
|
+
Types = Iterable[type] | UnionType
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
"""
|
|
@@ -211,7 +212,7 @@ class Container:
|
|
|
211
212
|
def __injectables(self) -> frozenset[Injectable]:
|
|
212
213
|
return frozenset(self.__data.values())
|
|
213
214
|
|
|
214
|
-
def update(self, classes:
|
|
215
|
+
def update(self, classes: Types, injectable: Injectable):
|
|
215
216
|
classes = frozenset(get_origins(*classes))
|
|
216
217
|
|
|
217
218
|
if classes:
|
|
@@ -308,7 +309,16 @@ class Module(EventListener):
|
|
|
308
309
|
yield from tuple(self.__modules)
|
|
309
310
|
yield self.__container
|
|
310
311
|
|
|
311
|
-
def
|
|
312
|
+
def set_constant(self, instance: _T, on: type | Types = None) -> _T:
|
|
313
|
+
cls = type(instance)
|
|
314
|
+
|
|
315
|
+
@self.injectable(on=(cls, on))
|
|
316
|
+
def get_constant():
|
|
317
|
+
return instance
|
|
318
|
+
|
|
319
|
+
return instance
|
|
320
|
+
|
|
321
|
+
def get_instance(self, cls: type[_T]) -> _T | None:
|
|
312
322
|
try:
|
|
313
323
|
injectable = self[cls]
|
|
314
324
|
except KeyError:
|
|
@@ -317,10 +327,10 @@ class Module(EventListener):
|
|
|
317
327
|
instance = injectable.get_instance()
|
|
318
328
|
return cast(cls, instance)
|
|
319
329
|
|
|
320
|
-
def get_lazy_instance(self, cls: type[_T]
|
|
330
|
+
def get_lazy_instance(self, cls: type[_T]) -> Lazy[_T | None]:
|
|
321
331
|
return Lazy(lambda: self.get_instance(cls))
|
|
322
332
|
|
|
323
|
-
def update(self, classes:
|
|
333
|
+
def update(self, classes: Types, injectable: Injectable):
|
|
324
334
|
self.__container.update(classes, injectable)
|
|
325
335
|
return self
|
|
326
336
|
|
|
@@ -548,39 +558,29 @@ class InjectableDecorator:
|
|
|
548
558
|
wrapped: Callable[..., Any] = None,
|
|
549
559
|
/,
|
|
550
560
|
*,
|
|
551
|
-
on: type |
|
|
561
|
+
on: type | Types = None,
|
|
552
562
|
):
|
|
553
563
|
def decorator(wp):
|
|
554
|
-
@lambda fn: fn()
|
|
555
|
-
def classes():
|
|
556
|
-
if cls := self.__get_class(wp):
|
|
557
|
-
yield cls
|
|
558
|
-
|
|
559
|
-
if on is None:
|
|
560
|
-
return
|
|
561
|
-
elif isinstance(on, type | str):
|
|
562
|
-
yield on
|
|
563
|
-
else:
|
|
564
|
-
yield from on
|
|
565
|
-
|
|
566
564
|
@self.__module.inject
|
|
567
565
|
@wraps(wp, updated=())
|
|
568
566
|
def factory(*args, **kwargs):
|
|
569
567
|
return wp(*args, **kwargs)
|
|
570
568
|
|
|
571
569
|
injectable = self.__injectable_type(factory)
|
|
570
|
+
classes = self.__get_classes(wp, on)
|
|
572
571
|
self.__module.update(classes, injectable)
|
|
573
|
-
|
|
574
572
|
return wp
|
|
575
573
|
|
|
576
574
|
return decorator(wrapped) if wrapped else decorator
|
|
577
575
|
|
|
578
|
-
@
|
|
579
|
-
def
|
|
580
|
-
|
|
581
|
-
|
|
576
|
+
@classmethod
|
|
577
|
+
def __get_classes(cls, *objects: Any) -> Iterator[type | UnionType]:
|
|
578
|
+
for obj in objects:
|
|
579
|
+
if isinstance(obj, Iterable) and not isinstance(obj, type | str):
|
|
580
|
+
yield from cls.__get_classes(*obj)
|
|
582
581
|
|
|
583
|
-
|
|
584
|
-
|
|
582
|
+
elif isfunction(obj):
|
|
583
|
+
yield get_annotations(obj, eval_str=True).get("return")
|
|
585
584
|
|
|
586
|
-
|
|
585
|
+
else:
|
|
586
|
+
yield obj
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-injection
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.8
|
|
4
4
|
Summary: Fast and easy dependency injection framework.
|
|
5
5
|
Home-page: https://github.com/100nm/python-injection
|
|
6
6
|
License: MIT
|
|
@@ -19,6 +19,8 @@ Description-Content-Type: text/markdown
|
|
|
19
19
|
|
|
20
20
|
## Create an injectable
|
|
21
21
|
|
|
22
|
+
> **Note**: If the class needs dependencies, these will be resolved when the instance is retrieved.
|
|
23
|
+
|
|
22
24
|
If you wish to inject a singleton, use `singleton` decorator.
|
|
23
25
|
|
|
24
26
|
```python
|
|
@@ -39,7 +41,14 @@ class Injectable:
|
|
|
39
41
|
""" class implementation """
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
If you have a constant (such as a global variable) and wish to register it as an injectable, use `set_constant`
|
|
45
|
+
function.
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from injection import set_constant
|
|
49
|
+
|
|
50
|
+
app = set_constant(Application())
|
|
51
|
+
```
|
|
43
52
|
|
|
44
53
|
## Inject an instance
|
|
45
54
|
|
|
@@ -57,6 +66,9 @@ def my_function(instance: Injectable):
|
|
|
57
66
|
If `inject` decorates a class, it will be applied to the `__init__` method.
|
|
58
67
|
_Especially useful for dataclasses:_
|
|
59
68
|
|
|
69
|
+
> **Note**: Doesn't work with Pydantic `BaseModel` because the signature of the `__init__` method doesn't contain the
|
|
70
|
+
> dependencies.
|
|
71
|
+
|
|
60
72
|
```python
|
|
61
73
|
from dataclasses import dataclass
|
|
62
74
|
|
|
@@ -68,9 +80,6 @@ class DataClass:
|
|
|
68
80
|
instance: Injectable = ...
|
|
69
81
|
```
|
|
70
82
|
|
|
71
|
-
> **Note**: Doesn't work with Pydantic `BaseModel` because the signature of the `__init__` method doesn't contain the
|
|
72
|
-
> dependencies.
|
|
73
|
-
|
|
74
83
|
## Get an instance
|
|
75
84
|
|
|
76
85
|
_Example with `get_instance` function:_
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
injection/__init__.py,sha256=9_AVJILxKIBiL_6KJSh2RRydgSHXH38uahAGD0S1-dI,20
|
|
2
|
-
injection/_pkg.py,sha256=
|
|
3
|
-
injection/_pkg.pyi,sha256=
|
|
2
|
+
injection/_pkg.py,sha256=7Ns-9VxyGeIf2fOVfOAa5rD_kxAcY1WSHGSkKYAW4T0,536
|
|
3
|
+
injection/_pkg.pyi,sha256=YfSr-pwahHfVx8wak4JxDcXsgrIohd2ZJ73GgysFLNA,4209
|
|
4
4
|
injection/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
injection/common/event.py,sha256=uFoGRnxxkohH53JEStn4tN2Pn79HlgGExh7VkXdBwVQ,1316
|
|
6
6
|
injection/common/lazy.py,sha256=HIefQ1z7ivgU791MDSwBmUcdST3bOv0sivSMyR2DfHc,1493
|
|
7
7
|
injection/common/tools/__init__.py,sha256=S2y9DaQ4EaTRty9fKpBtPXA7hSjkzgM5N2jFf5jcmJU,21
|
|
8
|
-
injection/common/tools/_type.py,sha256=
|
|
8
|
+
injection/common/tools/_type.py,sha256=3hElLUPtiG6_kmxeWiNabX5zNKN_m1vUc3gBVdOf9WY,887
|
|
9
9
|
injection/core/__init__.py,sha256=zuf0ubI2dHnbjn1059eduhS-ACIkkROa6-dhp10krh0,22
|
|
10
|
-
injection/core/module.py,sha256=
|
|
10
|
+
injection/core/module.py,sha256=Lm0uc0uUvVQLfnXwfH6xaXoHYuPvdbR8HgFXWrZmi5Y,15595
|
|
11
11
|
injection/exceptions.py,sha256=wd4OxmpneGEmlZ0yeNBfnCYfPYqUksfbmA2mopLNm_s,688
|
|
12
12
|
injection/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
injection/integrations/blacksheep.py,sha256=F4h85VS9dLGHn-ARDARYMB02Htsd3nKMT9Y-EF4cOqE,818
|
|
14
14
|
injection/utils.py,sha256=a4w2SXyXP1A8AC_4hyEypByVUZOwSFIA3lh8StLxuLY,590
|
|
15
|
-
python_injection-0.6.
|
|
16
|
-
python_injection-0.6.
|
|
17
|
-
python_injection-0.6.
|
|
15
|
+
python_injection-0.6.8.dist-info/METADATA,sha256=4E21PIf33RBie3Wje2_h58VBDSkBwhKGn7gZAuai6q0,3227
|
|
16
|
+
python_injection-0.6.8.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
17
|
+
python_injection-0.6.8.dist-info/RECORD,,
|
|
File without changes
|