omlish 0.0.0.dev432__py3-none-any.whl → 0.0.0.dev434__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.
- omlish/__about__.py +3 -3
- omlish/asyncs/all.py +0 -13
- omlish/inject/__init__.py +152 -126
- omlish/inject/binder.py +7 -4
- omlish/inject/impl/elements.py +6 -8
- omlish/inject/impl/injector.py +58 -32
- omlish/inject/impl/inspect.py +1 -0
- omlish/inject/impl/maysync.py +44 -0
- omlish/inject/impl/multis.py +5 -5
- omlish/inject/impl/privates.py +8 -8
- omlish/inject/impl/providers.py +24 -31
- omlish/inject/impl/providers2.py +43 -0
- omlish/inject/impl/scopes.py +19 -25
- omlish/inject/impl/sync.py +42 -0
- omlish/inject/injector.py +9 -11
- omlish/inject/inspect.py +1 -3
- omlish/inject/listeners.py +4 -4
- omlish/inject/managed.py +52 -20
- omlish/inject/maysync.py +27 -0
- omlish/inject/providers.py +6 -0
- omlish/inject/scopes.py +38 -10
- omlish/inject/sync.py +46 -0
- omlish/lang/__init__.py +23 -6
- omlish/lang/asyncs.py +18 -0
- omlish/lang/contextmanagers.py +23 -0
- omlish/lang/imports/capture.py +491 -0
- omlish/lang/imports/lazy.py +0 -25
- omlish/lang/imports/proxy.py +62 -0
- omlish/lang/imports/proxyinit.py +28 -518
- omlish/lang/resources.py +1 -1
- omlish/lite/asyncs.py +21 -0
- omlish/lite/maysync.py +21 -0
- omlish/logs/contexts.py +4 -3
- omlish/logs/std/records.py +29 -19
- omlish/logs/typed/bindings.py +84 -37
- omlish/logs/typed/types.py +16 -1
- omlish/marshal/__init__.py +1 -1
- omlish/typedvalues/__init__.py +1 -1
- {omlish-0.0.0.dev432.dist-info → omlish-0.0.0.dev434.dist-info}/METADATA +3 -6
- {omlish-0.0.0.dev432.dist-info → omlish-0.0.0.dev434.dist-info}/RECORD +44 -39
- omlish/asyncs/bridge.py +0 -359
- omlish/asyncs/utils.py +0 -18
- {omlish-0.0.0.dev432.dist-info → omlish-0.0.0.dev434.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev432.dist-info → omlish-0.0.0.dev434.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev432.dist-info → omlish-0.0.0.dev434.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev432.dist-info → omlish-0.0.0.dev434.dist-info}/top_level.txt +0 -0
omlish/inject/impl/privates.py
CHANGED
@@ -12,14 +12,14 @@ from ... import lang
|
|
12
12
|
from ..bindings import Binding
|
13
13
|
from ..eagers import Eager
|
14
14
|
from ..elements import Element
|
15
|
-
from ..injector import
|
15
|
+
from ..injector import AsyncInjector
|
16
16
|
from ..keys import Key
|
17
17
|
from ..privates import Expose
|
18
18
|
from ..privates import Private
|
19
19
|
from ..providers import Provider
|
20
20
|
from ..scopes import Singleton
|
21
21
|
from .elements import ElementCollection
|
22
|
-
from .injector import
|
22
|
+
from .injector import AsyncInjectorImpl
|
23
23
|
from .providers import InternalProvider
|
24
24
|
from .providers import ProviderImpl
|
25
25
|
|
@@ -47,8 +47,8 @@ class PrivateInjectorProviderImpl(ProviderImpl, lang.Final):
|
|
47
47
|
def providers(self) -> ta.Iterable[Provider]:
|
48
48
|
return ()
|
49
49
|
|
50
|
-
def provide(self, injector:
|
51
|
-
return check.isinstance(injector,
|
50
|
+
async def provide(self, injector: AsyncInjector) -> ta.Any:
|
51
|
+
return check.isinstance(injector, AsyncInjectorImpl).create_child(self.ec)
|
52
52
|
|
53
53
|
|
54
54
|
##
|
@@ -63,9 +63,9 @@ class ExposedPrivateProviderImpl(ProviderImpl, lang.Final):
|
|
63
63
|
def providers(self) -> ta.Iterable[Provider]:
|
64
64
|
return ()
|
65
65
|
|
66
|
-
def provide(self, injector:
|
67
|
-
pi = injector.provide(self.pik)
|
68
|
-
return pi.provide(self.k)
|
66
|
+
async def provide(self, injector: AsyncInjector) -> ta.Any:
|
67
|
+
pi = await injector.provide(self.pik)
|
68
|
+
return await pi.provide(self.k)
|
69
69
|
|
70
70
|
|
71
71
|
##
|
@@ -82,7 +82,7 @@ class PrivateInfo(lang.Final):
|
|
82
82
|
|
83
83
|
@cached.property
|
84
84
|
def pik(self) -> Key:
|
85
|
-
return Key(
|
85
|
+
return Key(AsyncInjectorImpl, tag=self.id)
|
86
86
|
|
87
87
|
@cached.function
|
88
88
|
def element_collection(self) -> ElementCollection:
|
omlish/inject/impl/providers.py
CHANGED
@@ -7,14 +7,14 @@ import typing as ta
|
|
7
7
|
|
8
8
|
from ... import dataclasses as dc
|
9
9
|
from ... import lang
|
10
|
-
from ..injector import
|
10
|
+
from ..injector import AsyncInjector
|
11
11
|
from ..inspect import KwargsTarget
|
12
|
+
from ..providers import AsyncFnProvider
|
12
13
|
from ..providers import ConstProvider
|
13
14
|
from ..providers import CtorProvider
|
14
15
|
from ..providers import FnProvider
|
15
16
|
from ..providers import LinkProvider
|
16
17
|
from ..providers import Provider
|
17
|
-
from .inspect import build_kwargs_target
|
18
18
|
|
19
19
|
|
20
20
|
##
|
@@ -27,7 +27,7 @@ class ProviderImpl(lang.Abstract):
|
|
27
27
|
raise NotImplementedError
|
28
28
|
|
29
29
|
@abc.abstractmethod
|
30
|
-
def provide(self, injector:
|
30
|
+
def provide(self, injector: AsyncInjector) -> ta.Awaitable[ta.Any]:
|
31
31
|
raise NotImplementedError
|
32
32
|
|
33
33
|
|
@@ -43,66 +43,59 @@ class InternalProvider(Provider):
|
|
43
43
|
|
44
44
|
|
45
45
|
@dc.dataclass(frozen=True, eq=False)
|
46
|
-
class
|
47
|
-
p:
|
46
|
+
class AsyncCallableProviderImpl(ProviderImpl, lang.Final):
|
47
|
+
p: AsyncFnProvider
|
48
48
|
kt: KwargsTarget
|
49
49
|
|
50
50
|
@property
|
51
51
|
def providers(self) -> ta.Iterable[Provider]:
|
52
52
|
return (self.p,)
|
53
53
|
|
54
|
-
def provide(self, injector:
|
55
|
-
return injector.inject(self.kt)
|
54
|
+
async def provide(self, injector: AsyncInjector) -> ta.Any:
|
55
|
+
return await (await injector.inject(self.kt))
|
56
56
|
|
57
57
|
|
58
58
|
##
|
59
59
|
|
60
60
|
|
61
61
|
@dc.dataclass(frozen=True, eq=False)
|
62
|
-
class
|
63
|
-
p:
|
62
|
+
class CallableProviderImpl(ProviderImpl, lang.Final):
|
63
|
+
p: FnProvider | CtorProvider
|
64
|
+
kt: KwargsTarget
|
64
65
|
|
65
66
|
@property
|
66
67
|
def providers(self) -> ta.Iterable[Provider]:
|
67
68
|
return (self.p,)
|
68
69
|
|
69
|
-
def provide(self, injector:
|
70
|
-
return self.
|
70
|
+
async def provide(self, injector: AsyncInjector) -> ta.Any:
|
71
|
+
return await injector.inject(self.kt)
|
71
72
|
|
72
73
|
|
73
74
|
##
|
74
75
|
|
75
76
|
|
76
77
|
@dc.dataclass(frozen=True, eq=False)
|
77
|
-
class
|
78
|
-
p:
|
78
|
+
class ConstProviderImpl(ProviderImpl, lang.Final):
|
79
|
+
p: ConstProvider
|
79
80
|
|
80
81
|
@property
|
81
82
|
def providers(self) -> ta.Iterable[Provider]:
|
82
83
|
return (self.p,)
|
83
84
|
|
84
|
-
def provide(self, injector:
|
85
|
-
return
|
85
|
+
async def provide(self, injector: AsyncInjector) -> ta.Any:
|
86
|
+
return self.p.v
|
86
87
|
|
87
88
|
|
88
89
|
##
|
89
90
|
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
ConstProvider: ConstProviderImpl,
|
95
|
-
LinkProvider: LinkProviderImpl,
|
96
|
-
InternalProvider: lambda p: p.impl,
|
97
|
-
}
|
98
|
-
|
92
|
+
@dc.dataclass(frozen=True, eq=False)
|
93
|
+
class LinkProviderImpl(ProviderImpl, lang.Final):
|
94
|
+
p: LinkProvider
|
99
95
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
except KeyError:
|
104
|
-
pass
|
105
|
-
else:
|
106
|
-
return fac(p)
|
96
|
+
@property
|
97
|
+
def providers(self) -> ta.Iterable[Provider]:
|
98
|
+
return (self.p,)
|
107
99
|
|
108
|
-
|
100
|
+
async def provide(self, injector: AsyncInjector) -> ta.Any:
|
101
|
+
return await injector.provide(self.p.k)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from ..providers import AsyncFnProvider
|
4
|
+
from ..providers import ConstProvider
|
5
|
+
from ..providers import CtorProvider
|
6
|
+
from ..providers import FnProvider
|
7
|
+
from ..providers import LinkProvider
|
8
|
+
from ..providers import Provider
|
9
|
+
from ..scopes import ScopeSeededProvider
|
10
|
+
from .inspect import build_kwargs_target
|
11
|
+
from .providers import AsyncCallableProviderImpl
|
12
|
+
from .providers import CallableProviderImpl
|
13
|
+
from .providers import ConstProviderImpl
|
14
|
+
from .providers import InternalProvider
|
15
|
+
from .providers import LinkProviderImpl
|
16
|
+
from .providers import ProviderImpl
|
17
|
+
from .scopes import ScopeSeededProviderImpl
|
18
|
+
|
19
|
+
|
20
|
+
##
|
21
|
+
|
22
|
+
|
23
|
+
PROVIDER_IMPLS_BY_PROVIDER: dict[type[Provider], ta.Callable[..., ProviderImpl]] = {
|
24
|
+
AsyncFnProvider: lambda p: AsyncCallableProviderImpl(p, build_kwargs_target(p.fn)),
|
25
|
+
FnProvider: lambda p: CallableProviderImpl(p, build_kwargs_target(p.fn)),
|
26
|
+
CtorProvider: lambda p: CallableProviderImpl(p, build_kwargs_target(p.ty)),
|
27
|
+
ConstProvider: ConstProviderImpl,
|
28
|
+
LinkProvider: LinkProviderImpl,
|
29
|
+
InternalProvider: lambda p: p.impl,
|
30
|
+
|
31
|
+
ScopeSeededProvider: ScopeSeededProviderImpl,
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
def make_provider_impl(p: Provider) -> ProviderImpl:
|
36
|
+
try:
|
37
|
+
fac = PROVIDER_IMPLS_BY_PROVIDER[type(p)]
|
38
|
+
except KeyError:
|
39
|
+
pass
|
40
|
+
else:
|
41
|
+
return fac(p)
|
42
|
+
|
43
|
+
raise TypeError(p)
|
omlish/inject/impl/scopes.py
CHANGED
@@ -17,7 +17,7 @@ from ..elements import Elements
|
|
17
17
|
from ..elements import as_elements
|
18
18
|
from ..errors import ScopeAlreadyOpenError
|
19
19
|
from ..errors import ScopeNotOpenError
|
20
|
-
from ..injector import
|
20
|
+
from ..injector import AsyncInjector
|
21
21
|
from ..keys import Key
|
22
22
|
from ..providers import FnProvider
|
23
23
|
from ..providers import Provider
|
@@ -28,14 +28,11 @@ from ..scopes import ThreadScope
|
|
28
28
|
from ..types import Scope
|
29
29
|
from ..types import Unscoped
|
30
30
|
from .bindings import BindingImpl
|
31
|
-
from .providers import PROVIDER_IMPLS_BY_PROVIDER
|
32
31
|
from .providers import ProviderImpl
|
33
32
|
|
34
33
|
|
35
|
-
|
36
|
-
from . import injector as
|
37
|
-
else:
|
38
|
-
injector_ = lang.proxy_import('.injector', __package__)
|
34
|
+
with lang.auto_proxy_import(globals()):
|
35
|
+
from . import injector as _injector
|
39
36
|
|
40
37
|
|
41
38
|
##
|
@@ -51,7 +48,7 @@ class ScopeImpl(lang.Abstract):
|
|
51
48
|
return None
|
52
49
|
|
53
50
|
@abc.abstractmethod
|
54
|
-
def provide(self, binding: BindingImpl, injector:
|
51
|
+
def provide(self, binding: BindingImpl, injector: AsyncInjector) -> ta.Awaitable[ta.Any]:
|
55
52
|
raise NotImplementedError
|
56
53
|
|
57
54
|
|
@@ -60,8 +57,8 @@ class UnscopedScopeImpl(ScopeImpl, lang.Final):
|
|
60
57
|
def scope(self) -> Unscoped:
|
61
58
|
return Unscoped()
|
62
59
|
|
63
|
-
def provide(self, binding: BindingImpl, injector:
|
64
|
-
return binding.provider.provide(injector)
|
60
|
+
async def provide(self, binding: BindingImpl, injector: AsyncInjector) -> ta.Any:
|
61
|
+
return await binding.provider.provide(injector)
|
65
62
|
|
66
63
|
|
67
64
|
class SingletonScopeImpl(ScopeImpl, lang.Final):
|
@@ -74,12 +71,12 @@ class SingletonScopeImpl(ScopeImpl, lang.Final):
|
|
74
71
|
def scope(self) -> Singleton:
|
75
72
|
return Singleton()
|
76
73
|
|
77
|
-
def provide(self, binding: BindingImpl, injector:
|
74
|
+
async def provide(self, binding: BindingImpl, injector: AsyncInjector) -> ta.Any:
|
78
75
|
try:
|
79
76
|
return self._dct[binding]
|
80
77
|
except KeyError:
|
81
78
|
pass
|
82
|
-
v = binding.provider.provide(injector)
|
79
|
+
v = await binding.provider.provide(injector)
|
83
80
|
self._dct[binding] = v
|
84
81
|
return v
|
85
82
|
|
@@ -94,7 +91,7 @@ class ThreadScopeImpl(ScopeImpl, lang.Final):
|
|
94
91
|
def scope(self) -> ThreadScope:
|
95
92
|
return ThreadScope()
|
96
93
|
|
97
|
-
def provide(self, binding: BindingImpl, injector:
|
94
|
+
async def provide(self, binding: BindingImpl, injector: AsyncInjector) -> ta.Any:
|
98
95
|
dct: dict[BindingImpl, ta.Any]
|
99
96
|
try:
|
100
97
|
dct = self._local.dct
|
@@ -104,7 +101,7 @@ class ThreadScopeImpl(ScopeImpl, lang.Final):
|
|
104
101
|
return dct[binding]
|
105
102
|
except KeyError:
|
106
103
|
pass
|
107
|
-
v = binding.provider.provide(injector)
|
104
|
+
v = await binding.provider.provide(injector)
|
108
105
|
dct[binding] = v
|
109
106
|
return v
|
110
107
|
|
@@ -120,15 +117,12 @@ class ScopeSeededProviderImpl(ProviderImpl):
|
|
120
117
|
def providers(self) -> ta.Iterable[Provider]:
|
121
118
|
return (self.p,)
|
122
119
|
|
123
|
-
def provide(self, injector:
|
124
|
-
ii = check.isinstance(injector,
|
120
|
+
async def provide(self, injector: AsyncInjector) -> ta.Any:
|
121
|
+
ii = check.isinstance(injector, _injector.AsyncInjectorImpl)
|
125
122
|
ssi = check.isinstance(ii.get_scope_impl(self.p.ss), SeededScopeImpl)
|
126
123
|
return ssi.must_state().seeds[self.p.key]
|
127
124
|
|
128
125
|
|
129
|
-
PROVIDER_IMPLS_BY_PROVIDER[ScopeSeededProvider] = ScopeSeededProviderImpl
|
130
|
-
|
131
|
-
|
132
126
|
class SeededScopeImpl(ScopeImpl):
|
133
127
|
@dc.dataclass(frozen=True)
|
134
128
|
class State:
|
@@ -151,20 +145,20 @@ class SeededScopeImpl(ScopeImpl):
|
|
151
145
|
return st
|
152
146
|
|
153
147
|
class Manager(SeededScope.Manager, lang.Final):
|
154
|
-
def __init__(self, ss: SeededScope, i:
|
148
|
+
def __init__(self, ss: SeededScope, i: AsyncInjector) -> None:
|
155
149
|
super().__init__()
|
156
150
|
|
157
151
|
self._ss = check.isinstance(ss, SeededScope)
|
158
|
-
self._ii = check.isinstance(i,
|
152
|
+
self._ii = check.isinstance(i, _injector.AsyncInjectorImpl)
|
159
153
|
self._ssi = check.isinstance(self._ii.get_scope_impl(self._ss), SeededScopeImpl)
|
160
154
|
|
161
|
-
@contextlib.
|
162
|
-
def __call__(self, seeds: ta.Mapping[Key, ta.Any]) -> ta.
|
155
|
+
@contextlib.asynccontextmanager
|
156
|
+
async def __call__(self, seeds: ta.Mapping[Key, ta.Any]) -> ta.AsyncGenerator[None]:
|
163
157
|
try:
|
164
158
|
if self._ssi._st is not None: # noqa
|
165
159
|
raise ScopeAlreadyOpenError(self._ss)
|
166
160
|
self._ssi._st = SeededScopeImpl.State(dict(seeds)) # noqa
|
167
|
-
self._ii._instantiate_eagers(self._ss) # noqa
|
161
|
+
await self._ii._instantiate_eagers(self._ss) # noqa
|
168
162
|
yield
|
169
163
|
finally:
|
170
164
|
if self._ssi._st is None: # noqa
|
@@ -180,13 +174,13 @@ class SeededScopeImpl(ScopeImpl):
|
|
180
174
|
),
|
181
175
|
)
|
182
176
|
|
183
|
-
def provide(self, binding: BindingImpl, injector:
|
177
|
+
async def provide(self, binding: BindingImpl, injector: AsyncInjector) -> ta.Any:
|
184
178
|
st = self.must_state()
|
185
179
|
try:
|
186
180
|
return st.prvs[binding]
|
187
181
|
except KeyError:
|
188
182
|
pass
|
189
|
-
v = binding.provider.provide(injector)
|
183
|
+
v = await binding.provider.provide(injector)
|
190
184
|
st.prvs[binding] = v
|
191
185
|
return v
|
192
186
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from ... import lang
|
4
|
+
from ..elements import Elements
|
5
|
+
from ..injector import AsyncInjector
|
6
|
+
from ..inspect import KwargsTarget
|
7
|
+
from ..keys import Key
|
8
|
+
from ..sync import Injector
|
9
|
+
from .elements import ElementCollection
|
10
|
+
from .injector import AsyncInjectorImpl
|
11
|
+
|
12
|
+
|
13
|
+
##
|
14
|
+
|
15
|
+
|
16
|
+
class InjectorImpl(Injector, lang.Final):
|
17
|
+
_ai: AsyncInjector
|
18
|
+
|
19
|
+
def try_provide(self, key: ta.Any) -> lang.Maybe[ta.Any]:
|
20
|
+
return lang.sync_await(self._ai.try_provide(key))
|
21
|
+
|
22
|
+
def provide(self, key: ta.Any) -> ta.Any:
|
23
|
+
return lang.sync_await(self._ai.provide(key))
|
24
|
+
|
25
|
+
def provide_kwargs(self, kt: KwargsTarget) -> ta.Mapping[str, ta.Any]:
|
26
|
+
return lang.sync_await(self._ai.provide_kwargs(kt))
|
27
|
+
|
28
|
+
def inject(self, obj: ta.Any) -> ta.Any:
|
29
|
+
return lang.sync_await(self._ai.inject(obj))
|
30
|
+
|
31
|
+
|
32
|
+
def create_injector(es: Elements) -> Injector:
|
33
|
+
si = InjectorImpl()
|
34
|
+
ai = AsyncInjectorImpl(
|
35
|
+
ElementCollection(es),
|
36
|
+
internal_consts={
|
37
|
+
Key(Injector): si,
|
38
|
+
},
|
39
|
+
)
|
40
|
+
si._ai = ai # noqa
|
41
|
+
lang.sync_await(ai._init()) # noqa
|
42
|
+
return si
|
omlish/inject/injector.py
CHANGED
@@ -8,10 +8,8 @@ from .inspect import KwargsTarget
|
|
8
8
|
from .keys import Key
|
9
9
|
|
10
10
|
|
11
|
-
|
11
|
+
with lang.auto_proxy_import(globals()):
|
12
12
|
from .impl import injector as _injector
|
13
|
-
else:
|
14
|
-
_injector = lang.proxy_import('.impl.injector', __package__)
|
15
13
|
|
16
14
|
|
17
15
|
T = ta.TypeVar('T')
|
@@ -20,29 +18,29 @@ T = ta.TypeVar('T')
|
|
20
18
|
##
|
21
19
|
|
22
20
|
|
23
|
-
class
|
21
|
+
class AsyncInjector(lang.Abstract):
|
24
22
|
@abc.abstractmethod
|
25
|
-
def try_provide(self, key: ta.Any) -> lang.Maybe[ta.Any]:
|
23
|
+
def try_provide(self, key: ta.Any) -> ta.Awaitable[lang.Maybe[ta.Any]]:
|
26
24
|
raise NotImplementedError
|
27
25
|
|
28
26
|
@abc.abstractmethod
|
29
|
-
def provide(self, key: ta.Any) -> ta.Any:
|
27
|
+
def provide(self, key: ta.Any) -> ta.Awaitable[ta.Any]:
|
30
28
|
raise NotImplementedError
|
31
29
|
|
32
30
|
@abc.abstractmethod
|
33
|
-
def provide_kwargs(self, kt: KwargsTarget) -> ta.Mapping[str, ta.Any]:
|
31
|
+
def provide_kwargs(self, kt: KwargsTarget) -> ta.Awaitable[ta.Mapping[str, ta.Any]]:
|
34
32
|
raise NotImplementedError
|
35
33
|
|
36
34
|
@abc.abstractmethod
|
37
|
-
def inject(self, obj: ta.Any) -> ta.Any:
|
35
|
+
def inject(self, obj: ta.Any) -> ta.Awaitable[ta.Any]:
|
38
36
|
raise NotImplementedError
|
39
37
|
|
40
38
|
def __getitem__(
|
41
39
|
self,
|
42
40
|
target: Key[T] | type[T],
|
43
|
-
) -> T:
|
41
|
+
) -> ta.Awaitable[T]:
|
44
42
|
return self.provide(target)
|
45
43
|
|
46
44
|
|
47
|
-
def
|
48
|
-
return _injector.
|
45
|
+
def create_async_injector(*args: Elemental) -> ta.Awaitable[AsyncInjector]:
|
46
|
+
return _injector.create_async_injector(as_elements(*args))
|
omlish/inject/inspect.py
CHANGED
omlish/inject/listeners.py
CHANGED
@@ -4,7 +4,7 @@ from .. import dataclasses as dc
|
|
4
4
|
from .. import lang
|
5
5
|
from .bindings import Binding
|
6
6
|
from .elements import Element
|
7
|
-
from .injector import
|
7
|
+
from .injector import AsyncInjector
|
8
8
|
from .keys import Key
|
9
9
|
|
10
10
|
|
@@ -12,11 +12,11 @@ from .keys import Key
|
|
12
12
|
|
13
13
|
|
14
14
|
ProvisionListener: ta.TypeAlias = ta.Callable[[
|
15
|
-
|
15
|
+
AsyncInjector,
|
16
16
|
Key,
|
17
17
|
Binding | None,
|
18
|
-
ta.Callable[[], ta.Any],
|
19
|
-
], ta.
|
18
|
+
ta.Callable[[], ta.Awaitable[ta.Any]],
|
19
|
+
], ta.Awaitable[ta.Any]]
|
20
20
|
|
21
21
|
|
22
22
|
@dc.dataclass(frozen=True)
|
omlish/inject/managed.py
CHANGED
@@ -9,14 +9,12 @@ from .. import lang
|
|
9
9
|
from .binder import bind
|
10
10
|
from .elements import Elemental
|
11
11
|
from .impl.inspect import build_kwargs_target
|
12
|
-
from .injector import Injector
|
13
|
-
from .injector import create_injector
|
14
12
|
|
15
13
|
|
16
|
-
|
17
|
-
from
|
18
|
-
|
19
|
-
|
14
|
+
with lang.auto_proxy_import(globals()):
|
15
|
+
from . import injector as _injector
|
16
|
+
from . import maysync as _maysync
|
17
|
+
from . import sync as _sync
|
20
18
|
|
21
19
|
|
22
20
|
T = ta.TypeVar('T')
|
@@ -25,9 +23,43 @@ T = ta.TypeVar('T')
|
|
25
23
|
##
|
26
24
|
|
27
25
|
|
26
|
+
@contextlib.asynccontextmanager
|
27
|
+
async def create_async_managed_injector(*args: Elemental) -> ta.AsyncGenerator['_injector.AsyncInjector']:
|
28
|
+
ai = await _injector.create_async_injector(
|
29
|
+
bind(contextlib.AsyncExitStack, singleton=True, eager=True),
|
30
|
+
*args,
|
31
|
+
)
|
32
|
+
async with (await ai[contextlib.AsyncExitStack]):
|
33
|
+
yield ai
|
34
|
+
|
35
|
+
|
36
|
+
def make_async_managed_provider(
|
37
|
+
fac: ta.Callable[..., T],
|
38
|
+
*fns: ta.Callable[[T], ta.AsyncContextManager[T]],
|
39
|
+
) -> ta.Callable[..., ta.Awaitable[T]]:
|
40
|
+
kt = build_kwargs_target(fac)
|
41
|
+
|
42
|
+
async def _provide(
|
43
|
+
ai: _injector.AsyncInjector,
|
44
|
+
aes: contextlib.AsyncExitStack,
|
45
|
+
):
|
46
|
+
obj = await ai.inject(kt)
|
47
|
+
if not fns:
|
48
|
+
obj = await aes.enter_async_context(obj)
|
49
|
+
else:
|
50
|
+
for fn in fns:
|
51
|
+
await aes.enter_async_context(fn(obj))
|
52
|
+
return obj
|
53
|
+
|
54
|
+
return _provide
|
55
|
+
|
56
|
+
|
57
|
+
##
|
58
|
+
|
59
|
+
|
28
60
|
@contextlib.contextmanager
|
29
|
-
def create_managed_injector(*args: Elemental) -> ta.Generator[Injector]:
|
30
|
-
i = create_injector(
|
61
|
+
def create_managed_injector(*args: Elemental) -> ta.Generator['_sync.Injector']:
|
62
|
+
i = _sync.create_injector(
|
31
63
|
bind(contextlib.ExitStack, singleton=True, eager=True),
|
32
64
|
*args,
|
33
65
|
)
|
@@ -42,7 +74,7 @@ def make_managed_provider(
|
|
42
74
|
kt = build_kwargs_target(fac)
|
43
75
|
|
44
76
|
def _provide(
|
45
|
-
i: Injector,
|
77
|
+
i: _sync.Injector,
|
46
78
|
es: contextlib.ExitStack,
|
47
79
|
):
|
48
80
|
obj = i.inject(kt)
|
@@ -59,32 +91,32 @@ def make_managed_provider(
|
|
59
91
|
##
|
60
92
|
|
61
93
|
|
62
|
-
@contextlib.
|
63
|
-
|
64
|
-
i =
|
65
|
-
bind(contextlib.
|
94
|
+
@contextlib.contextmanager
|
95
|
+
def create_maysync_managed_injector(*args: Elemental) -> ta.Generator['_maysync.MaysyncInjector']:
|
96
|
+
i = _maysync.create_maysync_injector(
|
97
|
+
bind(contextlib.ExitStack, singleton=True, eager=True),
|
66
98
|
*args,
|
67
99
|
)
|
68
|
-
|
100
|
+
with i[contextlib.ExitStack]:
|
69
101
|
yield i
|
70
102
|
|
71
103
|
|
72
|
-
def
|
104
|
+
def make_maysync_managed_provider(
|
73
105
|
fac: ta.Callable[..., T],
|
74
|
-
*fns: ta.Callable[[T], ta.
|
106
|
+
*fns: ta.Callable[[T], ta.ContextManager[T]],
|
75
107
|
) -> ta.Callable[..., T]:
|
76
108
|
kt = build_kwargs_target(fac)
|
77
109
|
|
78
110
|
def _provide(
|
79
|
-
i:
|
80
|
-
|
111
|
+
i: _maysync.MaysyncInjector,
|
112
|
+
es: contextlib.ExitStack,
|
81
113
|
):
|
82
114
|
obj = i.inject(kt)
|
83
115
|
if not fns:
|
84
|
-
obj =
|
116
|
+
obj = es.enter_context(obj)
|
85
117
|
else:
|
86
118
|
for fn in fns:
|
87
|
-
|
119
|
+
es.enter_context(fn(obj))
|
88
120
|
return obj
|
89
121
|
|
90
122
|
return _provide
|
omlish/inject/maysync.py
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from .. import lang
|
4
|
+
from .elements import Elemental
|
5
|
+
from .elements import as_elements
|
6
|
+
from .sync import Injector
|
7
|
+
|
8
|
+
|
9
|
+
with lang.auto_proxy_import(globals()):
|
10
|
+
from .impl import maysync as _maysync
|
11
|
+
|
12
|
+
|
13
|
+
T = ta.TypeVar('T')
|
14
|
+
|
15
|
+
|
16
|
+
##
|
17
|
+
|
18
|
+
|
19
|
+
class MaysyncInjector(Injector, lang.Abstract):
|
20
|
+
pass
|
21
|
+
|
22
|
+
|
23
|
+
##
|
24
|
+
|
25
|
+
|
26
|
+
def create_maysync_injector(*args: Elemental) -> MaysyncInjector:
|
27
|
+
return _maysync.create_maysync_injector(as_elements(*args))
|
omlish/inject/providers.py
CHANGED
@@ -17,6 +17,12 @@ class Provider(lang.Abstract):
|
|
17
17
|
pass
|
18
18
|
|
19
19
|
|
20
|
+
@dc.dataclass(frozen=True)
|
21
|
+
@dc.extra_class_params(cache_hash=True)
|
22
|
+
class AsyncFnProvider(Provider):
|
23
|
+
fn: ta.Any = dc.xfield(validate=callable)
|
24
|
+
|
25
|
+
|
20
26
|
@dc.dataclass(frozen=True)
|
21
27
|
@dc.extra_class_params(cache_hash=True)
|
22
28
|
class FnProvider(Provider):
|