ashka-lifecycle 0.2.0__tar.gz → 0.2.2__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.
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/PKG-INFO +1 -1
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/pyproject.toml +1 -1
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/pyproject.toml.orig +1 -1
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/src/ashka_lifecycle/__init__.py +4 -0
- ashka_lifecycle-0.2.2/src/ashka_lifecycle/async_container.py +51 -0
- ashka_lifecycle-0.2.2/src/ashka_lifecycle/container.py +44 -0
- ashka_lifecycle-0.2.2/src/ashka_lifecycle/provider/make_factory.py +110 -0
- ashka_lifecycle-0.2.0/src/ashka_lifecycle/async_container.py +0 -42
- ashka_lifecycle-0.2.0/src/ashka_lifecycle/container.py +0 -37
- ashka_lifecycle-0.2.0/src/ashka_lifecycle/provider/make_factory.py +0 -92
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/README.md +0 -0
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/src/ashka_lifecycle/entities/bootstrap.py +0 -0
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/src/ashka_lifecycle/entities/scope.py +0 -0
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/src/ashka_lifecycle/provider/__init__.py +0 -0
- {ashka_lifecycle-0.2.0 → ashka_lifecycle-0.2.2}/src/ashka_lifecycle/py.typed +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import ashka_lifecycle.async_container
|
|
2
|
+
import ashka_lifecycle.container
|
|
1
3
|
from ashka_lifecycle.entities.scope import AshkaScope
|
|
2
4
|
from ashka_lifecycle.provider import (
|
|
3
5
|
provide, # pyright: ignore[reportUnknownVariableType]
|
|
@@ -16,3 +18,5 @@ def activate_lifecycle() -> None:
|
|
|
16
18
|
Call this function manually before importing dishka to ensure that the
|
|
17
19
|
dishka lifecycle is activated in advance.
|
|
18
20
|
"""
|
|
21
|
+
ashka_lifecycle.container.activate()
|
|
22
|
+
ashka_lifecycle.async_container.activate()
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from asyncio import gather
|
|
2
|
+
from collections.abc import Callable, Coroutine
|
|
3
|
+
from logging import getLogger
|
|
4
|
+
|
|
5
|
+
from ashka_lifecycle.entities.bootstrap import (
|
|
6
|
+
bootstrap_types,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from dishka import AsyncContainer, Scope
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def activate(): ...
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
_logger = getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
_aenter: Callable[..., Coroutine[None, object, AsyncContainer]] = (
|
|
18
|
+
AsyncContainer.__aenter__
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def __aenter__(self: AsyncContainer) -> AsyncContainer:
|
|
23
|
+
aenter: AsyncContainer = await _aenter(self)
|
|
24
|
+
|
|
25
|
+
if self.scope is Scope.APP:
|
|
26
|
+
_logger.debug("Initiating bootstrap factories.")
|
|
27
|
+
await gather(
|
|
28
|
+
*(
|
|
29
|
+
self.get(key.type_hint, key.component)
|
|
30
|
+
for key in self.registry.factories
|
|
31
|
+
if key.type_hint in bootstrap_types
|
|
32
|
+
)
|
|
33
|
+
)
|
|
34
|
+
else:
|
|
35
|
+
_logger.debug(
|
|
36
|
+
f"'<dishka_container>.scope': {self.scope!r} is not 'Scope.APP', skipping bootstrap"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
return aenter
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
async def init(self: AsyncContainer) -> None:
|
|
43
|
+
if not self.scope is Scope.APP:
|
|
44
|
+
_logger.warning(
|
|
45
|
+
f"'<dishka_container>.scope': {self.scope!r} is not 'Scope.APP', 'container.init()' won't do any bootstrap."
|
|
46
|
+
)
|
|
47
|
+
await self.__aenter__()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
AsyncContainer.__aenter__ = __aenter__
|
|
51
|
+
AsyncContainer.init = init # pyright: ignore[reportAttributeAccessIssue]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from logging import getLogger
|
|
3
|
+
|
|
4
|
+
from ashka_lifecycle.entities.bootstrap import (
|
|
5
|
+
bootstrap_types,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
from dishka import Container, Scope
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def activate(): ...
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_logger = getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
_enter: Callable[..., Container] = Container.__enter__
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def __enter__(self: Container) -> Container:
|
|
20
|
+
enter: Container = _enter(self)
|
|
21
|
+
|
|
22
|
+
if self.scope is Scope.APP:
|
|
23
|
+
_logger.debug("Initiating bootstrap factories.")
|
|
24
|
+
for key in self.registry.factories:
|
|
25
|
+
if key.type_hint in bootstrap_types:
|
|
26
|
+
self.get(key.type_hint, key.component)
|
|
27
|
+
else:
|
|
28
|
+
_logger.debug(
|
|
29
|
+
f"'<dishka_container>.scope': {self.scope!r} is not 'Scope.APP', skipping bootstrap"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
return enter
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def init(self: Container) -> None:
|
|
36
|
+
if not self.scope is Scope.APP:
|
|
37
|
+
_logger.warning(
|
|
38
|
+
f"'<dishka_container>.scope': {self.scope!r} is not 'Scope.APP', 'container.init()' won't do any bootstrap."
|
|
39
|
+
)
|
|
40
|
+
self.__enter__()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
Container.__enter__ = __enter__
|
|
44
|
+
Container.init = init # pyright: ignore[reportAttributeAccessIssue]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from inspect import isbuiltin, isclass, isfunction
|
|
3
|
+
from logging import getLogger
|
|
4
|
+
from typing import Any, NewType, get_origin, get_type_hints, overload
|
|
5
|
+
|
|
6
|
+
from ashka_lifecycle.entities.bootstrap import (
|
|
7
|
+
bootstrap_types,
|
|
8
|
+
)
|
|
9
|
+
from ashka_lifecycle.entities.scope import AshkaScope
|
|
10
|
+
|
|
11
|
+
from dishka import BaseScope, Scope
|
|
12
|
+
from dishka import provide as _provide # pyright: ignore[reportUnknownVariableType]
|
|
13
|
+
from dishka.dependency_source.composite import CompositeDependencySource
|
|
14
|
+
from dishka.entities.provides_marker import ProvideMultiple
|
|
15
|
+
from dishka.provider.exceptions import MissingReturnHintError
|
|
16
|
+
from dishka.provider.make_factory import (
|
|
17
|
+
ProvideSource,
|
|
18
|
+
_clean_result_hint, # pyright: ignore[reportPrivateUsage]
|
|
19
|
+
_guess_factory_type, # pyright: ignore[reportPrivateUsage]
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__: list[str] = ["provide"]
|
|
23
|
+
|
|
24
|
+
_logger = getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def activate(): ...
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@overload
|
|
31
|
+
def provide(
|
|
32
|
+
*, scope: BaseScope | AshkaScope | None = None, **kwargs: Any
|
|
33
|
+
) -> Callable[[Callable[..., Any]], CompositeDependencySource]: ...
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@overload
|
|
37
|
+
def provide(
|
|
38
|
+
source: ProvideSource, # pyright: ignore[reportUnknownParameterType]
|
|
39
|
+
*,
|
|
40
|
+
scope: BaseScope | AshkaScope | None = None,
|
|
41
|
+
**kwargs: Any,
|
|
42
|
+
) -> CompositeDependencySource: ...
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def provide(
|
|
46
|
+
source: ProvideSource | None = None, # pyright: ignore[reportUnknownParameterType]
|
|
47
|
+
*,
|
|
48
|
+
scope: BaseScope | AshkaScope | None = None,
|
|
49
|
+
**kwargs: Any,
|
|
50
|
+
) -> (
|
|
51
|
+
CompositeDependencySource
|
|
52
|
+
| Callable[
|
|
53
|
+
[Callable[..., Any]],
|
|
54
|
+
CompositeDependencySource,
|
|
55
|
+
]
|
|
56
|
+
):
|
|
57
|
+
if scope is not AshkaScope.BOOTSTRAP:
|
|
58
|
+
return _provide(source, scope=scope, **kwargs)
|
|
59
|
+
|
|
60
|
+
def scoped(source: ProvideSource) -> CompositeDependencySource: # pyright: ignore[reportUnknownParameterType]
|
|
61
|
+
_logger.debug(
|
|
62
|
+
f"Adding {getattr(source, '__name__', source)!r} to bootstrap list..." # pyright: ignore[reportUnknownArgumentType]
|
|
63
|
+
)
|
|
64
|
+
bootstrap_types.add(
|
|
65
|
+
new_type := NewType(
|
|
66
|
+
"ashka_lifecycle.provider.make_factory.provide", AshkaScope
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
try:
|
|
70
|
+
return (
|
|
71
|
+
_provide(
|
|
72
|
+
source,
|
|
73
|
+
scope=Scope.APP,
|
|
74
|
+
provides=ProvideMultiple[
|
|
75
|
+
new_type, (_kwargs := kwargs.copy()).pop(provides) # pyright: ignore[reportInvalidTypeArguments]
|
|
76
|
+
],
|
|
77
|
+
**_kwargs,
|
|
78
|
+
)
|
|
79
|
+
if (provides := "provides") in kwargs
|
|
80
|
+
else _provide(
|
|
81
|
+
source,
|
|
82
|
+
scope=Scope.APP,
|
|
83
|
+
provides=ProvideMultiple[
|
|
84
|
+
new_type,
|
|
85
|
+
source # pyright: ignore[reportInvalidTypeArguments]
|
|
86
|
+
if isclass(source) or isclass(get_origin(source)) # pyright: ignore[reportUnknownArgumentType]
|
|
87
|
+
else _clean_result_hint(
|
|
88
|
+
_guess_factory_type(
|
|
89
|
+
func := getattr(source, "__func__", None) # pyright: ignore[reportUnknownVariableType, reportUnknownArgumentType]
|
|
90
|
+
or (
|
|
91
|
+
source
|
|
92
|
+
if isfunction(source) or isbuiltin(source) # pyright: ignore[reportUnknownArgumentType]
|
|
93
|
+
else getattr(
|
|
94
|
+
source.__call__, # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType, reportUnknownArgumentType]
|
|
95
|
+
"__func__",
|
|
96
|
+
source.__call__, # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType, reportUnknownArgumentType]
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
),
|
|
100
|
+
get_type_hints(func)["return"], # pyright: ignore[reportUnknownArgumentType]
|
|
101
|
+
),
|
|
102
|
+
],
|
|
103
|
+
**kwargs,
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
except KeyError as e:
|
|
107
|
+
bootstrap_types.remove(new_type)
|
|
108
|
+
raise MissingReturnHintError(source) from e
|
|
109
|
+
|
|
110
|
+
return scoped if source is None else scoped(source) # pyright: ignore[reportUnknownVariableType]
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
from asyncio import gather
|
|
2
|
-
from collections.abc import Callable, Coroutine
|
|
3
|
-
|
|
4
|
-
from ashka_lifecycle.entities.bootstrap import (
|
|
5
|
-
bootstrap_types,
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
from dishka import AsyncContainer
|
|
9
|
-
|
|
10
|
-
_aenter: Callable[..., Coroutine[None, object, AsyncContainer]] = (
|
|
11
|
-
AsyncContainer.__aenter__
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
async def __aenter__(self: AsyncContainer) -> AsyncContainer:
|
|
16
|
-
aenter: AsyncContainer = await _aenter(self)
|
|
17
|
-
|
|
18
|
-
await gather(
|
|
19
|
-
*(
|
|
20
|
-
self.get(key.type_hint, key.component)
|
|
21
|
-
for registry in iter(
|
|
22
|
-
lambda state=[self.registry]: (
|
|
23
|
-
(state[0], state.__setitem__(0, state[0].child_registry))[0] # pyright: ignore[reportCallIssue, reportArgumentType]
|
|
24
|
-
if state[0] is not None # pyright: ignore[reportUnnecessaryComparison]
|
|
25
|
-
else None
|
|
26
|
-
),
|
|
27
|
-
None,
|
|
28
|
-
)
|
|
29
|
-
for key in registry.factories
|
|
30
|
-
if key.type_hint in bootstrap_types
|
|
31
|
-
)
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
return aenter
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
async def init(self: AsyncContainer) -> None:
|
|
38
|
-
await self.__aenter__()
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
AsyncContainer.__aenter__ = __aenter__
|
|
42
|
-
AsyncContainer.init = init # pyright: ignore[reportAttributeAccessIssue]
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
|
|
3
|
-
from ashka_lifecycle.entities.bootstrap import (
|
|
4
|
-
bootstrap_types,
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
from dishka import Container
|
|
8
|
-
|
|
9
|
-
_enter: Callable[..., Container] = Container.__enter__
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def __enter__(self: Container) -> Container:
|
|
13
|
-
enter: Container = _enter(self)
|
|
14
|
-
|
|
15
|
-
[
|
|
16
|
-
self.get(key.type_hint, key.component)
|
|
17
|
-
for registry in iter(
|
|
18
|
-
lambda state=[self.registry]: (
|
|
19
|
-
(state[0], state.__setitem__(0, state[0].child_registry))[0] # pyright: ignore[reportCallIssue, reportArgumentType]
|
|
20
|
-
if state[0] is not None # pyright: ignore[reportUnnecessaryComparison]
|
|
21
|
-
else None
|
|
22
|
-
),
|
|
23
|
-
None,
|
|
24
|
-
)
|
|
25
|
-
for key in registry.factories
|
|
26
|
-
if key.type_hint in bootstrap_types
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
return enter
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def init(self: Container) -> None:
|
|
33
|
-
self.__enter__()
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Container.__enter__ = __enter__
|
|
37
|
-
Container.init = init # pyright: ignore[reportAttributeAccessIssue]
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
from collections.abc import Callable
|
|
2
|
-
from inspect import isbuiltin, isclass, isfunction
|
|
3
|
-
from typing import Any, NewType, get_origin, get_type_hints, overload
|
|
4
|
-
|
|
5
|
-
from ashka_lifecycle.entities.bootstrap import (
|
|
6
|
-
bootstrap_types,
|
|
7
|
-
)
|
|
8
|
-
from ashka_lifecycle.entities.scope import AshkaScope
|
|
9
|
-
|
|
10
|
-
from dishka import BaseScope, Scope
|
|
11
|
-
from dishka import provide as _provide # pyright: ignore[reportUnknownVariableType]
|
|
12
|
-
from dishka.dependency_source.composite import CompositeDependencySource
|
|
13
|
-
from dishka.entities.provides_marker import ProvideMultiple
|
|
14
|
-
from dishka.provider.make_factory import (
|
|
15
|
-
ProvideSource,
|
|
16
|
-
_clean_result_hint, # pyright: ignore[reportPrivateUsage]
|
|
17
|
-
_guess_factory_type, # pyright: ignore[reportPrivateUsage]
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
__all__: list[str] = ["provide"]
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@overload
|
|
24
|
-
def provide(
|
|
25
|
-
*, scope: BaseScope | AshkaScope | None = None, **kwargs: Any
|
|
26
|
-
) -> Callable[[Callable[..., Any]], CompositeDependencySource]: ...
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@overload
|
|
30
|
-
def provide(
|
|
31
|
-
source: ProvideSource, # pyright: ignore[reportUnknownParameterType]
|
|
32
|
-
*,
|
|
33
|
-
scope: BaseScope | AshkaScope | None = None,
|
|
34
|
-
**kwargs: Any,
|
|
35
|
-
) -> CompositeDependencySource: ...
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def provide(
|
|
39
|
-
source: ProvideSource | None = None, # pyright: ignore[reportUnknownParameterType]
|
|
40
|
-
*,
|
|
41
|
-
scope: BaseScope | AshkaScope | None = None,
|
|
42
|
-
**kwargs: Any,
|
|
43
|
-
) -> (
|
|
44
|
-
CompositeDependencySource
|
|
45
|
-
| Callable[
|
|
46
|
-
[Callable[..., Any]],
|
|
47
|
-
CompositeDependencySource,
|
|
48
|
-
]
|
|
49
|
-
):
|
|
50
|
-
if scope is not AshkaScope.BOOTSTRAP:
|
|
51
|
-
return _provide(source, scope=scope, **kwargs)
|
|
52
|
-
|
|
53
|
-
def scoped(source: ProvideSource) -> CompositeDependencySource: # pyright: ignore[reportUnknownParameterType]
|
|
54
|
-
return (
|
|
55
|
-
_provide(
|
|
56
|
-
source,
|
|
57
|
-
scope=Scope.APP,
|
|
58
|
-
provides=ProvideMultiple[
|
|
59
|
-
new_type, (_kwargs := kwargs.copy()).pop(provides) # pyright: ignore[reportInvalidTypeArguments]
|
|
60
|
-
],
|
|
61
|
-
**_kwargs,
|
|
62
|
-
)
|
|
63
|
-
if bootstrap_types.add(new_type := NewType("_", object)) is None
|
|
64
|
-
and (provides := "provides") in kwargs
|
|
65
|
-
else _provide(
|
|
66
|
-
source,
|
|
67
|
-
scope=Scope.APP,
|
|
68
|
-
provides=ProvideMultiple[
|
|
69
|
-
new_type,
|
|
70
|
-
source # pyright: ignore[reportInvalidTypeArguments]
|
|
71
|
-
if isclass(source) or isclass(get_origin(source)) # pyright: ignore[reportUnknownArgumentType]
|
|
72
|
-
else _clean_result_hint(
|
|
73
|
-
_guess_factory_type(
|
|
74
|
-
func := getattr(source, "__func__", None) # pyright: ignore[reportUnknownVariableType, reportUnknownArgumentType]
|
|
75
|
-
or (
|
|
76
|
-
source
|
|
77
|
-
if isfunction(source) or isbuiltin(source) # pyright: ignore[reportUnknownArgumentType]
|
|
78
|
-
else getattr(
|
|
79
|
-
source.__call__, # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType, reportUnknownArgumentType]
|
|
80
|
-
"__func__",
|
|
81
|
-
source.__call__, # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType, reportUnknownArgumentType]
|
|
82
|
-
)
|
|
83
|
-
)
|
|
84
|
-
),
|
|
85
|
-
get_type_hints(func)["return"], # pyright: ignore[reportUnknownArgumentType]
|
|
86
|
-
),
|
|
87
|
-
],
|
|
88
|
-
**kwargs,
|
|
89
|
-
)
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
return scoped if source is None else scoped(source) # pyright: ignore[reportUnknownVariableType]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|