dependency-injection-pattern 0.0.0__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.
- dependency_injection_pattern-0.0.0.dist-info/METADATA +104 -0
- dependency_injection_pattern-0.0.0.dist-info/RECORD +36 -0
- dependency_injection_pattern-0.0.0.dist-info/WHEEL +5 -0
- dependency_injection_pattern-0.0.0.dist-info/licenses/LICENSE +21 -0
- dependency_injection_pattern-0.0.0.dist-info/top_level.txt +1 -0
- di/__init__.py +13 -0
- di/core/container.py +336 -0
- di/core/default_scope.py +71 -0
- di/core/exceptions/add_exception.py +7 -0
- di/core/exceptions/container_sealed_error.py +5 -0
- di/core/exceptions/factory_provide_exception.py +25 -0
- di/core/exceptions/implementation_exception.py +13 -0
- di/core/exceptions/provide_exception.py +22 -0
- di/core/exceptions/seal_exception.py +9 -0
- di/core/factories/dependency.py +38 -0
- di/core/factories/factory.py +105 -0
- di/core/factories/scoped_factory.py +18 -0
- di/core/factories/singleton_factory.py +32 -0
- di/core/factories/transient_factory.py +17 -0
- di/core/factory.py +24 -0
- di/core/helpers.py +51 -0
- di/core/log.py +4 -0
- di/core/named_service.py +3 -0
- di/core/protocols/container.py +25 -0
- di/core/protocols/factory.py +7 -0
- di/core/protocols/provider.py +24 -0
- di/core/provider.py +85 -0
- di/core/reflection/__init__.py +126 -0
- di/core/reflection/parameter.py +66 -0
- di/core/reflection/parameter_kind.py +9 -0
- di/core/reflection/parameter_mapper.py +55 -0
- di/core/reflection/signature.py +45 -0
- di/core/reflection/undefined.py +24 -0
- di/core/scope.py +15 -0
- di/core/service_request.py +26 -0
- di/exceptions.py +15 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from inspect import Parameter
|
|
3
|
+
|
|
4
|
+
class ParameterKind(Enum):
|
|
5
|
+
POSITIONAL = Parameter.POSITIONAL_ONLY
|
|
6
|
+
KEYWORD = Parameter.KEYWORD_ONLY
|
|
7
|
+
POSITIONAL_OR_KEYWORD = Parameter.POSITIONAL_OR_KEYWORD
|
|
8
|
+
ARGS = Parameter.VAR_POSITIONAL
|
|
9
|
+
KWARGS = Parameter.VAR_KEYWORD
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import Iterator, Mapping, Iterable, Sequence
|
|
2
|
+
|
|
3
|
+
from di.core.reflection.parameter import Parameter
|
|
4
|
+
|
|
5
|
+
class ParameterMapper(Iterable[Parameter]):
|
|
6
|
+
__slots__ = ["__parameters", "__index"]
|
|
7
|
+
|
|
8
|
+
def __init__(self, parameters: Sequence[Parameter]):
|
|
9
|
+
self.__parameters = list(parameters)
|
|
10
|
+
self.__index: Mapping[str, int] | None = None
|
|
11
|
+
|
|
12
|
+
def __get_index(self) -> Mapping[str, int]:
|
|
13
|
+
if not self.__index:
|
|
14
|
+
self.__index = {
|
|
15
|
+
parameter.name: self.__parameters.index(parameter)
|
|
16
|
+
for parameter in self.__parameters
|
|
17
|
+
}
|
|
18
|
+
return self.__index # pragma: no cover
|
|
19
|
+
|
|
20
|
+
def __getitem__(self, index: int | str) -> Parameter: # pragma: no cover
|
|
21
|
+
if isinstance(index, int):
|
|
22
|
+
return self.__parameters[index]
|
|
23
|
+
else:
|
|
24
|
+
p_index = self.__get_index()
|
|
25
|
+
|
|
26
|
+
if index in p_index:
|
|
27
|
+
return self.__parameters[p_index[index]]
|
|
28
|
+
else:
|
|
29
|
+
raise KeyError(index)
|
|
30
|
+
|
|
31
|
+
def __iter__(self) -> Iterator[Parameter]:
|
|
32
|
+
return iter(self.__parameters)
|
|
33
|
+
|
|
34
|
+
def __len__(self) -> int: # pragma: no cover
|
|
35
|
+
return len(self.__parameters)
|
|
36
|
+
|
|
37
|
+
def __delitem__(self, index: int | str) -> None: # pragma: no cover
|
|
38
|
+
if isinstance(index, int):
|
|
39
|
+
del self.__parameters[index]
|
|
40
|
+
else:
|
|
41
|
+
p_index = self.__get_index()
|
|
42
|
+
|
|
43
|
+
if index in p_index:
|
|
44
|
+
del self.__parameters[p_index[index]]
|
|
45
|
+
else:
|
|
46
|
+
raise KeyError(index)
|
|
47
|
+
|
|
48
|
+
def __contains__(self, name: str) -> bool: # pragma: no cover
|
|
49
|
+
p_index = self.__get_index()
|
|
50
|
+
return name in p_index
|
|
51
|
+
|
|
52
|
+
def __eq__(self, o: object) -> bool: # pragma: no cover
|
|
53
|
+
if isinstance(o, ParameterMapper):
|
|
54
|
+
return self.__parameters == o.__parameters
|
|
55
|
+
return False
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from typingutils import get_type_name
|
|
3
|
+
|
|
4
|
+
from di.core.reflection.parameter_mapper import ParameterMapper
|
|
5
|
+
|
|
6
|
+
class Signature:
|
|
7
|
+
__slots__ = ["__parameters", "__return_type"]
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
parameters: ParameterMapper,
|
|
12
|
+
return_type: type[Any]
|
|
13
|
+
):
|
|
14
|
+
self.__parameters = parameters
|
|
15
|
+
self.__return_type = return_type
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def parameters(self) -> ParameterMapper:
|
|
19
|
+
"""The signature parameters
|
|
20
|
+
"""
|
|
21
|
+
return self.__parameters
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def return_type(self) -> type[Any]:
|
|
25
|
+
"""The signature return type
|
|
26
|
+
"""
|
|
27
|
+
return self.__return_type
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def __repr__(self) -> str:
|
|
32
|
+
str_parameters = ", ".join([ str(p) for p in self.__parameters ]) if self.__parameters else ""
|
|
33
|
+
str_return = f" -> {get_type_name(self.__return_type)}" if self.__return_type else ""
|
|
34
|
+
return f"({str_parameters}){str_return}"
|
|
35
|
+
|
|
36
|
+
def __eq__(self, o: object) -> bool: # pragma: no cover
|
|
37
|
+
if self is o:
|
|
38
|
+
return True
|
|
39
|
+
elif isinstance(o, Signature):
|
|
40
|
+
return (
|
|
41
|
+
self.parameters == o.parameters
|
|
42
|
+
and self.return_type == o.return_type
|
|
43
|
+
)
|
|
44
|
+
return False
|
|
45
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from inspect import Signature, Parameter
|
|
2
|
+
|
|
3
|
+
class Meta(type): # pragma: no cover
|
|
4
|
+
|
|
5
|
+
def __bool__(self):
|
|
6
|
+
return False
|
|
7
|
+
|
|
8
|
+
def __eq__(self, other: object) -> bool:
|
|
9
|
+
return other is Undefined or other in [ Signature.empty, Parameter.empty, None ]
|
|
10
|
+
|
|
11
|
+
def __repr__(cls):
|
|
12
|
+
return "Undefined"
|
|
13
|
+
|
|
14
|
+
def __str__(self) -> str:
|
|
15
|
+
return "Undefined"
|
|
16
|
+
|
|
17
|
+
def __hash__(self) -> int:
|
|
18
|
+
return type.__hash__(self)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Undefined(metaclass=Meta):
|
|
22
|
+
def __new__(cls):
|
|
23
|
+
raise Exception("Undefined type is not supposed to be instantiated") # pragma: no cover
|
|
24
|
+
|
di/core/scope.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from typing import Callable, TypeVar
|
|
4
|
+
|
|
5
|
+
T = TypeVar('T')
|
|
6
|
+
|
|
7
|
+
class Scope(ABC):
|
|
8
|
+
"""
|
|
9
|
+
Scope is the base class from which scopes are derived, and its superclasses handle provision of
|
|
10
|
+
scoped services.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
@abstractmethod
|
|
14
|
+
def provide(self, service: type[T], factory: Callable[..., T]) -> T:
|
|
15
|
+
...
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from typing import TypeVar, Generic
|
|
2
|
+
|
|
3
|
+
T = TypeVar("T")
|
|
4
|
+
|
|
5
|
+
class ServiceRequest(Generic[T]):
|
|
6
|
+
"""
|
|
7
|
+
The ServiceRequest[T] class is used internally to request a service by name.
|
|
8
|
+
"""
|
|
9
|
+
__slots__ = ["__name", "__type", "__default"]
|
|
10
|
+
|
|
11
|
+
def __init__(self, name: str, type: type[T], default: T):
|
|
12
|
+
self.__name = name.lower()
|
|
13
|
+
self.__type = type
|
|
14
|
+
self.__default = default
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def name(self) -> str:
|
|
18
|
+
return self.__name
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def type(self) -> type[T]:
|
|
22
|
+
return self.__type
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def default(self) -> T:
|
|
26
|
+
return self.__default
|
di/exceptions.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from di.core.exceptions.add_exception import AddException
|
|
2
|
+
from di.core.exceptions.implementation_exception import ImplementationException
|
|
3
|
+
from di.core.exceptions.factory_provide_exception import FactoryProvideException
|
|
4
|
+
from di.core.exceptions.container_sealed_error import ContainerSealedError
|
|
5
|
+
from di.core.exceptions.seal_exception import SealException
|
|
6
|
+
from di.core.exceptions.provide_exception import ProvideException
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
'AddException',
|
|
10
|
+
'ImplementationException',
|
|
11
|
+
'FactoryProvideException',
|
|
12
|
+
'ContainerSealedError',
|
|
13
|
+
'SealException',
|
|
14
|
+
'ProvideException'
|
|
15
|
+
]
|