omlish 0.0.0.dev433__py3-none-any.whl → 0.0.0.dev435__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.
Files changed (54) hide show
  1. omlish/__about__.py +2 -2
  2. omlish/asyncs/all.py +0 -13
  3. omlish/concurrent/__init__.py +0 -17
  4. omlish/concurrent/all.py +17 -0
  5. omlish/configs/types.py +1 -1
  6. omlish/daemons/__init__.py +70 -0
  7. omlish/dataclasses/errors.py +1 -1
  8. omlish/formats/json/stream/lexing.py +12 -6
  9. omlish/formats/json/stream/utils.py +28 -2
  10. omlish/formats/json5/stream.py +82 -0
  11. omlish/funcs/genmachine.py +1 -1
  12. omlish/http/coro/server/server.py +1 -1
  13. omlish/inject/__init__.py +152 -126
  14. omlish/inject/binder.py +7 -4
  15. omlish/inject/impl/elements.py +6 -8
  16. omlish/inject/impl/injector.py +58 -32
  17. omlish/inject/impl/inspect.py +1 -0
  18. omlish/inject/impl/maysync.py +44 -0
  19. omlish/inject/impl/multis.py +5 -5
  20. omlish/inject/impl/privates.py +8 -8
  21. omlish/inject/impl/providers.py +24 -31
  22. omlish/inject/impl/providers2.py +43 -0
  23. omlish/inject/impl/scopes.py +19 -25
  24. omlish/inject/impl/sync.py +42 -0
  25. omlish/inject/injector.py +9 -11
  26. omlish/inject/inspect.py +1 -3
  27. omlish/inject/listeners.py +4 -4
  28. omlish/inject/managed.py +52 -20
  29. omlish/inject/maysync.py +27 -0
  30. omlish/inject/providers.py +6 -0
  31. omlish/inject/scopes.py +38 -10
  32. omlish/inject/sync.py +46 -0
  33. omlish/lang/__init__.py +12 -3
  34. omlish/lang/asyncs.py +18 -0
  35. omlish/lang/contextmanagers.py +23 -0
  36. omlish/lite/asyncs.py +21 -0
  37. omlish/lite/attrops.py +1 -1
  38. omlish/lite/inject.py +4 -4
  39. omlish/lite/maysync.py +21 -0
  40. omlish/marshal/__init__.py +20 -8
  41. omlish/os/atomics.py +1 -1
  42. omlish/reflect/ops.py +9 -0
  43. omlish/reflect/types.py +19 -6
  44. omlish/sockets/addresses.py +1 -1
  45. omlish/sql/queries/params.py +1 -1
  46. {omlish-0.0.0.dev433.dist-info → omlish-0.0.0.dev435.dist-info}/METADATA +1 -4
  47. {omlish-0.0.0.dev433.dist-info → omlish-0.0.0.dev435.dist-info}/RECORD +51 -47
  48. omlish/asyncs/bridge.py +0 -359
  49. omlish/asyncs/utils.py +0 -18
  50. omlish/formats/json5/streams.py +0 -22
  51. {omlish-0.0.0.dev433.dist-info → omlish-0.0.0.dev435.dist-info}/WHEEL +0 -0
  52. {omlish-0.0.0.dev433.dist-info → omlish-0.0.0.dev435.dist-info}/entry_points.txt +0 -0
  53. {omlish-0.0.0.dev433.dist-info → omlish-0.0.0.dev435.dist-info}/licenses/LICENSE +0 -0
  54. {omlish-0.0.0.dev433.dist-info → omlish-0.0.0.dev435.dist-info}/top_level.txt +0 -0
@@ -47,14 +47,12 @@ from .multis import make_multi_provider_impl
47
47
  from .origins import Origins
48
48
  from .origins import set_origins
49
49
  from .providers import ProviderImpl
50
- from .providers import make_provider_impl
50
+ from .providers2 import make_provider_impl
51
51
  from .scopes import make_scope_impl
52
52
 
53
53
 
54
- if ta.TYPE_CHECKING:
55
- from . import privates as privates_
56
- else:
57
- privates_ = lang.proxy_import('.privates', __package__)
54
+ with lang.auto_proxy_import(globals()):
55
+ from . import privates as _privates
58
56
 
59
57
 
60
58
  ElementT = ta.TypeVar('ElementT', bound=Element)
@@ -69,17 +67,17 @@ class ElementCollection(lang.Final):
69
67
 
70
68
  self._es = check.isinstance(es, Elements)
71
69
 
72
- self._private_infos: ta.MutableMapping[Private, privates_.PrivateInfo] | None = None
70
+ self._private_infos: ta.MutableMapping[Private, _privates.PrivateInfo] | None = None
73
71
 
74
72
  ##
75
73
 
76
- def _get_private_info(self, p: Private) -> 'privates_.PrivateInfo':
74
+ def _get_private_info(self, p: Private) -> '_privates.PrivateInfo':
77
75
  if (pis := self._private_infos) is None:
78
76
  self._private_infos = pis = col.IdentityKeyDict()
79
77
  try:
80
78
  return pis[p]
81
79
  except KeyError:
82
- pis[p] = ec = privates_.PrivateInfo(self, p)
80
+ pis[p] = ec = _privates.PrivateInfo(self, p)
83
81
  return ec
84
82
 
85
83
  ##
@@ -25,7 +25,7 @@ from ...logs import all as logs
25
25
  from ..elements import Elements
26
26
  from ..errors import CyclicDependencyError
27
27
  from ..errors import UnboundKeyError
28
- from ..injector import Injector
28
+ from ..injector import AsyncInjector
29
29
  from ..inspect import KwargsTarget
30
30
  from ..keys import Key
31
31
  from ..keys import as_key
@@ -55,15 +55,22 @@ DEFAULT_SCOPES: list[Scope] = [
55
55
  ]
56
56
 
57
57
 
58
- class InjectorImpl(Injector, lang.Final):
59
- def __init__(self, ec: ElementCollection, p: ta.Optional['InjectorImpl'] = None) -> None:
58
+ class AsyncInjectorImpl(AsyncInjector, lang.Final):
59
+ def __init__(
60
+ self,
61
+ ec: ElementCollection,
62
+ p: ta.Optional['AsyncInjectorImpl'] = None,
63
+ *,
64
+ internal_consts: dict[Key, ta.Any] | None = None,
65
+ ) -> None:
60
66
  super().__init__()
61
67
 
62
68
  self._ec = check.isinstance(ec, ElementCollection)
63
- self._p: InjectorImpl | None = check.isinstance(p, (InjectorImpl, None))
69
+ self._p: AsyncInjectorImpl | None = check.isinstance(p, (AsyncInjectorImpl, None))
64
70
 
65
71
  self._internal_consts: dict[Key, ta.Any] = {
66
- Key(Injector): self,
72
+ Key(AsyncInjector): self,
73
+ **(internal_consts or {}),
67
74
  }
68
75
 
69
76
  self._bim = ec.binding_impl_map()
@@ -76,10 +83,10 @@ class InjectorImpl(Injector, lang.Final):
76
83
  )
77
84
  )
78
85
 
79
- self._cs: weakref.WeakSet[InjectorImpl] | None = None
80
- self._root: InjectorImpl = p._root if p is not None else self # noqa
86
+ self._cs: weakref.WeakSet[AsyncInjectorImpl] | None = None
87
+ self._root: AsyncInjectorImpl = p._root if p is not None else self # noqa
81
88
 
82
- self.__cur_req: InjectorImpl._Request | None = None
89
+ self.__cur_req: AsyncInjectorImpl._Request | None = None
83
90
 
84
91
  ss = [
85
92
  *DEFAULT_SCOPES,
@@ -89,27 +96,41 @@ class InjectorImpl(Injector, lang.Final):
89
96
  s: make_scope_impl(s) for s in ss
90
97
  }
91
98
 
92
- self._instantiate_eagers(Unscoped())
93
- self._instantiate_eagers(Singleton())
99
+ #
100
+
101
+ _has_run_init: bool = False
102
+
103
+ async def _init(self) -> bool:
104
+ if self._has_run_init:
105
+ return False
106
+
107
+ self._has_run_init = True
108
+
109
+ await self._instantiate_eagers(Unscoped())
110
+ await self._instantiate_eagers(Singleton())
94
111
 
95
- _root: 'InjectorImpl'
112
+ return True
96
113
 
97
- def _instantiate_eagers(self, sc: Scope) -> None:
114
+ #
115
+
116
+ _root: 'AsyncInjectorImpl'
117
+
118
+ async def _instantiate_eagers(self, sc: Scope) -> None:
98
119
  for k in self._ekbs.get(sc, ()):
99
- self.provide(k)
120
+ await self.provide(k)
100
121
 
101
122
  def get_scope_impl(self, sc: Scope) -> ScopeImpl:
102
123
  return self._scopes[sc]
103
124
 
104
- def create_child(self, ec: ElementCollection) -> Injector:
105
- c = InjectorImpl(ec, self)
125
+ def create_child(self, ec: ElementCollection) -> AsyncInjector:
126
+ c = AsyncInjectorImpl(ec, self)
106
127
  if self._cs is None:
107
128
  self._cs = weakref.WeakSet()
108
129
  self._cs.add(c)
109
130
  return c
110
131
 
111
132
  class _Request:
112
- def __init__(self, injector: 'InjectorImpl') -> None:
133
+ def __init__(self, injector: 'AsyncInjectorImpl') -> None:
113
134
  super().__init__()
114
135
 
115
136
  self._injector = injector
@@ -162,10 +183,13 @@ class InjectorImpl(Injector, lang.Final):
162
183
  finally:
163
184
  self.__cur_req = None
164
185
 
165
- def _try_provide(self, key: ta.Any, *, source: ta.Any = None) -> lang.Maybe[ta.Any]:
186
+ async def _try_provide(self, key: ta.Any, *, source: ta.Any = None) -> lang.Maybe[ta.Any]:
187
+ if not self._has_run_init:
188
+ await self._init()
189
+
166
190
  key = as_key(key)
167
191
 
168
- cr: InjectorImpl._Request
192
+ cr: AsyncInjectorImpl._Request
169
193
  with self._current_request() as cr:
170
194
  with cr.push_source(source):
171
195
  if (rv := cr.handle_key(key)).present:
@@ -182,55 +206,57 @@ class InjectorImpl(Injector, lang.Final):
182
206
  fn = lambda: sc.provide(bi, self) # noqa
183
207
  for pl in self._pls:
184
208
  fn = functools.partial(pl, self, key, bi.binding, fn)
185
- v = fn()
209
+ v = await fn()
186
210
 
187
211
  return cr.handle_provision(key, lang.just(v))
188
212
 
189
213
  if self._p is not None:
190
- pv = self._p._try_provide(key, source=source) # noqa
214
+ pv = await self._p._try_provide(key, source=source) # noqa
191
215
  if pv.present:
192
216
  return cr.handle_provision(key, pv)
193
217
 
194
218
  return cr.handle_provision(key, lang.empty())
195
219
 
196
- def _provide(self, key: ta.Any, *, source: ta.Any = None) -> ta.Any:
197
- v = self._try_provide(key, source=source)
220
+ async def _provide(self, key: ta.Any, *, source: ta.Any = None) -> ta.Any:
221
+ v = await self._try_provide(key, source=source)
198
222
  if v.present:
199
223
  return v.must()
200
224
  raise UnboundKeyError(key)
201
225
 
202
226
  #
203
227
 
204
- def try_provide(self, key: ta.Any) -> lang.Maybe[ta.Any]:
228
+ def try_provide(self, key: ta.Any) -> ta.Awaitable[lang.Maybe[ta.Any]]:
205
229
  return self._try_provide(key)
206
230
 
207
- def provide(self, key: ta.Any) -> ta.Any:
208
- v = self._try_provide(key)
231
+ async def provide(self, key: ta.Any) -> ta.Any:
232
+ v = await self._try_provide(key)
209
233
  if v.present:
210
234
  return v.must()
211
235
  raise UnboundKeyError(key)
212
236
 
213
- def provide_kwargs(self, kt: KwargsTarget) -> ta.Mapping[str, ta.Any]:
237
+ async def provide_kwargs(self, kt: KwargsTarget) -> ta.Mapping[str, ta.Any]:
214
238
  ret: dict[str, ta.Any] = {}
215
239
  for kw in kt.kwargs:
216
240
  if kw.has_default:
217
- if not (mv := self._try_provide(kw.key, source=kt)).present:
241
+ if not (mv := await self._try_provide(kw.key, source=kt)).present:
218
242
  continue
219
243
  v = mv.must()
220
244
  else:
221
- v = self._provide(kw.key, source=kt)
245
+ v = await self._provide(kw.key, source=kt)
222
246
  ret[kw.name] = v
223
247
  return ret
224
248
 
225
- def inject(self, obj: ta.Any) -> ta.Any:
249
+ async def inject(self, obj: ta.Any) -> ta.Any:
226
250
  if isinstance(obj, KwargsTarget):
227
251
  obj, kt = obj.obj, obj
228
252
  else:
229
253
  kt = build_kwargs_target(obj)
230
- kws = self.provide_kwargs(kt)
254
+ kws = await self.provide_kwargs(kt)
231
255
  # FIXME: still 'injecting' (as in has a req) if ctor needs and uses Injector
232
256
  return obj(**kws)
233
257
 
234
258
 
235
- def create_injector(es: Elements) -> Injector:
236
- return InjectorImpl(ElementCollection(es))
259
+ async def create_async_injector(es: Elements) -> AsyncInjector:
260
+ i = AsyncInjectorImpl(ElementCollection(es))
261
+ await i._init() # noqa
262
+ return i
@@ -4,6 +4,7 @@ TODO:
4
4
  - tag annotations? x: ta.Annotated[int, inj.Tag('foo')]
5
5
  - tag decorator - @inj.tag(x='foo')
6
6
  - *unpack optional here*
7
+ - use ...metadata
7
8
  """
8
9
  import dataclasses as dc
9
10
  import inspect
@@ -0,0 +1,44 @@
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 ..maysync import MaysyncInjector
9
+ from ..sync import Injector
10
+ from .elements import ElementCollection
11
+ from .injector import AsyncInjectorImpl
12
+
13
+
14
+ ##
15
+
16
+
17
+ class MaysyncInjectorImpl(MaysyncInjector, lang.Final):
18
+ _ai: AsyncInjector
19
+
20
+ def try_provide(self, key: ta.Any) -> lang.Maybe[ta.Any]:
21
+ return lang.run_maysync(self._ai.try_provide(key))
22
+
23
+ def provide(self, key: ta.Any) -> ta.Any:
24
+ return lang.run_maysync(self._ai.provide(key))
25
+
26
+ def provide_kwargs(self, kt: KwargsTarget) -> ta.Mapping[str, ta.Any]:
27
+ return lang.run_maysync(self._ai.provide_kwargs(kt))
28
+
29
+ def inject(self, obj: ta.Any) -> ta.Any:
30
+ return lang.run_maysync(self._ai.inject(obj))
31
+
32
+
33
+ def create_maysync_injector(es: Elements) -> MaysyncInjector:
34
+ si = MaysyncInjectorImpl()
35
+ ai = AsyncInjectorImpl(
36
+ ElementCollection(es),
37
+ internal_consts={
38
+ Key(MaysyncInjector): si,
39
+ Key(Injector): si,
40
+ },
41
+ )
42
+ si._ai = ai # noqa
43
+ lang.run_maysync(ai._init()) # noqa
44
+ return si
@@ -3,7 +3,7 @@ import typing as ta
3
3
  from ... import dataclasses as dc
4
4
  from ... import lang
5
5
  from ..elements import Element
6
- from ..injector import Injector
6
+ from ..injector import AsyncInjector
7
7
  from ..multis import MapBinding
8
8
  from ..multis import MapProvider
9
9
  from ..multis import SetBinding
@@ -26,10 +26,10 @@ class SetProviderImpl(ProviderImpl, lang.Final):
26
26
  for p in self.ps:
27
27
  yield from p.providers
28
28
 
29
- def provide(self, injector: Injector) -> ta.Any:
29
+ async def provide(self, injector: AsyncInjector) -> ta.Any:
30
30
  rv = set()
31
31
  for ep in self.ps:
32
- o = ep.provide(injector)
32
+ o = await ep.provide(injector)
33
33
  rv.add(o)
34
34
  return rv
35
35
 
@@ -47,10 +47,10 @@ class MapProviderImpl(ProviderImpl, lang.Final):
47
47
  for e in self.es:
48
48
  yield from e.v.providers
49
49
 
50
- def provide(self, injector: Injector) -> ta.Any:
50
+ async def provide(self, injector: AsyncInjector) -> ta.Any:
51
51
  rv = {}
52
52
  for e in self.es:
53
- o = e.v.provide(injector)
53
+ o = await e.v.provide(injector)
54
54
  rv[e.k] = o
55
55
  return rv
56
56
 
@@ -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 Injector
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 InjectorImpl
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: Injector) -> ta.Any:
51
- return check.isinstance(injector, InjectorImpl).create_child(self.ec)
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: Injector) -> ta.Any:
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(InjectorImpl, tag=self.id)
85
+ return Key(AsyncInjectorImpl, tag=self.id)
86
86
 
87
87
  @cached.function
88
88
  def element_collection(self) -> ElementCollection:
@@ -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 Injector
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: Injector) -> ta.Any:
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 CallableProviderImpl(ProviderImpl, lang.Final):
47
- p: FnProvider | CtorProvider
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: Injector) -> ta.Any:
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 ConstProviderImpl(ProviderImpl, lang.Final):
63
- p: ConstProvider
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: Injector) -> ta.Any:
70
- return self.p.v
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 LinkProviderImpl(ProviderImpl, lang.Final):
78
- p: LinkProvider
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: Injector) -> ta.Any:
85
- return injector.provide(self.p.k)
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
- PROVIDER_IMPLS_BY_PROVIDER: dict[type[Provider], ta.Callable[..., ProviderImpl]] = {
92
- FnProvider: lambda p: CallableProviderImpl(p, build_kwargs_target(p.fn)),
93
- CtorProvider: lambda p: CallableProviderImpl(p, build_kwargs_target(p.ty)),
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
- def make_provider_impl(p: Provider) -> ProviderImpl:
101
- try:
102
- fac = PROVIDER_IMPLS_BY_PROVIDER[type(p)]
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
- raise TypeError(p)
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)
@@ -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 Injector
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
- if ta.TYPE_CHECKING:
36
- from . import injector as injector_
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: Injector) -> ta.Any:
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: Injector) -> ta.Any:
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: Injector) -> ta.Any:
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: Injector) -> ta.Any:
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: Injector) -> ta.Any:
124
- ii = check.isinstance(injector, injector_.InjectorImpl)
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: Injector) -> None:
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, injector_.InjectorImpl)
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.contextmanager
162
- def __call__(self, seeds: ta.Mapping[Key, ta.Any]) -> ta.Generator[None]:
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: Injector) -> ta.Any:
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