omlish 0.0.0.dev484__py3-none-any.whl → 0.0.0.dev493__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 omlish might be problematic. Click here for more details.

Files changed (62) hide show
  1. omlish/README.md +199 -0
  2. omlish/__about__.py +8 -3
  3. omlish/dataclasses/impl/generation/plans.py +2 -17
  4. omlish/dataclasses/impl/generation/processor.py +2 -2
  5. omlish/dataclasses/impl/processing/driving.py +13 -1
  6. omlish/diag/_pycharm/runhack.py +1 -1
  7. omlish/inject/__init__.py +19 -11
  8. omlish/inject/_dataclasses.py +1485 -1323
  9. omlish/inject/binder.py +7 -4
  10. omlish/inject/eagers.py +2 -0
  11. omlish/inject/helpers/late.py +76 -0
  12. omlish/inject/{managed.py → helpers/managed.py} +10 -10
  13. omlish/inject/impl/elements.py +7 -4
  14. omlish/inject/impl/injector.py +10 -7
  15. omlish/inject/inspect.py +1 -1
  16. omlish/lang/__init__.py +2 -0
  17. omlish/lifecycles/README.md +30 -0
  18. omlish/lifecycles/__init__.py +87 -13
  19. omlish/lifecycles/_dataclasses.py +1388 -0
  20. omlish/lifecycles/base.py +178 -64
  21. omlish/lifecycles/contextmanagers.py +113 -4
  22. omlish/lifecycles/controller.py +150 -87
  23. omlish/lifecycles/injection.py +143 -0
  24. omlish/lifecycles/listeners.py +56 -0
  25. omlish/lifecycles/managed.py +142 -0
  26. omlish/lifecycles/manager.py +218 -93
  27. omlish/lifecycles/states.py +2 -0
  28. omlish/lifecycles/transitions.py +3 -0
  29. omlish/lifecycles/unwrap.py +57 -0
  30. omlish/lite/typing.py +18 -0
  31. omlish/logs/_amalg.py +1 -1
  32. omlish/logs/all.py +25 -11
  33. omlish/logs/asyncs.py +73 -0
  34. omlish/logs/base.py +101 -12
  35. omlish/logs/contexts.py +4 -1
  36. omlish/logs/lists.py +125 -0
  37. omlish/logs/modules.py +19 -1
  38. omlish/logs/std/loggers.py +6 -1
  39. omlish/logs/std/noisy.py +11 -9
  40. omlish/logs/{standard.py → std/standard.py} +3 -4
  41. omlish/logs/utils.py +16 -1
  42. omlish/marshal/_dataclasses.py +781 -781
  43. omlish/reflect/__init__.py +43 -26
  44. omlish/reflect/ops.py +10 -1
  45. omlish/specs/jmespath/_dataclasses.py +559 -559
  46. omlish/specs/jsonschema/keywords/_dataclasses.py +220 -220
  47. omlish/sql/__init__.py +24 -5
  48. omlish/sql/api/dbapi.py +1 -1
  49. omlish/sql/dbapi/__init__.py +15 -0
  50. omlish/sql/{dbapi.py → dbapi/drivers.py} +2 -2
  51. omlish/sql/queries/__init__.py +3 -0
  52. omlish/testing/pytest/plugins/asyncs/plugin.py +2 -0
  53. omlish/text/docwrap/cli.py +5 -0
  54. {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev493.dist-info}/METADATA +8 -5
  55. {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev493.dist-info}/RECORD +61 -51
  56. omlish/lifecycles/abstract.py +0 -86
  57. /omlish/inject/{impl → helpers}/proxy.py +0 -0
  58. /omlish/sql/{abc.py → dbapi/abc.py} +0 -0
  59. {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev493.dist-info}/WHEEL +0 -0
  60. {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev493.dist-info}/entry_points.txt +0 -0
  61. {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev493.dist-info}/licenses/LICENSE +0 -0
  62. {omlish-0.0.0.dev484.dist-info → omlish-0.0.0.dev493.dist-info}/top_level.txt +0 -0
@@ -1,163 +1,226 @@
1
- import abc
2
1
  import typing as ta
3
2
 
4
3
  from .. import check
5
4
  from .. import lang
6
- from .base import AnyLifecycle # noqa
7
- from .base import Lifecycle # noqa
5
+ from .base import AsyncLifecycle
6
+ from .base import Lifecycle
7
+ from .listeners import AsyncLifecycleListener
8
+ from .listeners import LifecycleListener
8
9
  from .states import LifecycleState
9
10
  from .states import LifecycleStates
10
11
  from .transitions import LifecycleTransition
11
12
  from .transitions import LifecycleTransitions
12
13
 
13
14
 
14
- R = ta.TypeVar('R')
15
-
16
- AnyLifecycleT = ta.TypeVar('AnyLifecycleT', bound='AnyLifecycle')
17
-
18
- LifecycleT = ta.TypeVar('LifecycleT', bound='Lifecycle')
19
-
20
-
21
15
  ##
22
16
 
23
17
 
24
- class AnyLifecycleListener(ta.Generic[AnyLifecycleT, R]):
25
- def on_starting(self, obj: AnyLifecycleT) -> R | None:
26
- return None
27
-
28
- def on_started(self, obj: AnyLifecycleT) -> R | None:
29
- return None
30
-
31
- def on_stopping(self, obj: AnyLifecycleT) -> R | None:
32
- return None
33
-
34
- def on_stopped(self, obj: AnyLifecycleT) -> R | None:
35
- return None
36
-
37
-
38
- class AnyLifecycleController(AnyLifecycle[R], lang.Abstract, ta.Generic[AnyLifecycleT, R]):
18
+ @ta.final
19
+ class LifecycleController(Lifecycle, lang.Final):
39
20
  def __init__(
40
21
  self,
41
- lifecycle: AnyLifecycleT,
22
+ controlled: Lifecycle,
23
+ *,
24
+ lock: lang.DefaultLockable = None,
42
25
  ) -> None:
43
26
  super().__init__()
44
27
 
45
- self._lifecycle: AnyLifecycleT = check.isinstance(lifecycle, AnyLifecycle) # type: ignore
28
+ self._controlled: Lifecycle = check.isinstance(controlled, Lifecycle)
29
+ self._lock = lang.default_lock(lock, None)
46
30
 
47
31
  self._state = LifecycleStates.NEW
48
- self._listeners: list[AnyLifecycleListener[AnyLifecycleT, R]] = []
32
+ self._listeners: list[LifecycleListener] = []
33
+
34
+ __repr__ = lang.attr_ops(lambda o: (o.controlled, o.state)).repr
49
35
 
50
- __repr__ = lang.attr_ops(lambda o: (o.lifecycle, o.state)).repr
36
+ #
51
37
 
52
38
  @property
53
- def lifecycle(self) -> AnyLifecycleT:
54
- return self._lifecycle
39
+ def controlled(self) -> Lifecycle:
40
+ return self._controlled
55
41
 
56
42
  @property
57
43
  def state(self) -> LifecycleState:
58
44
  return self._state
59
45
 
60
- def add_listener(self, listener: AnyLifecycleListener[AnyLifecycleT, R]) -> ta.Self:
61
- self._listeners.append(check.isinstance(listener, AnyLifecycleListener))
46
+ def add_listener(self, listener: LifecycleListener) -> ta.Self:
47
+ self._listeners.append(check.isinstance(listener, LifecycleListener))
62
48
  return self
63
49
 
64
- @abc.abstractmethod
50
+ #
51
+
52
+ def _set_state(self, state: LifecycleState) -> None:
53
+ self._state = state
54
+ self._controlled.lifecycle_state(state)
55
+
65
56
  def _advance(
66
57
  self,
67
58
  transition: LifecycleTransition,
68
- lifecycle_fn: ta.Callable[[], R | None],
69
- pre_listener_fn: ta.Callable[
70
- [AnyLifecycleListener[AnyLifecycleT, R]],
71
- ta.Callable[[AnyLifecycleT], R | None],
72
- ] | None = None,
73
- post_listener_fn: ta.Callable[
74
- [AnyLifecycleListener[AnyLifecycleT, R]],
75
- ta.Callable[[AnyLifecycleT], R | None],
76
- ] | None = None,
77
- ) -> R | None:
78
- raise NotImplementedError
59
+ controlled_fn: ta.Callable[[], None],
60
+ pre_listener_fn: ta.Callable[[LifecycleListener], ta.Callable[[Lifecycle], None]] | None = None,
61
+ post_listener_fn: ta.Callable[[LifecycleListener], ta.Callable[[Lifecycle], None]] | None = None,
62
+ ) -> None:
63
+ with self._lock():
64
+ if pre_listener_fn is not None:
65
+ for listener in self._listeners:
66
+ pre_listener_fn(listener)(self._controlled)
67
+
68
+ check.state(self._state in transition.old)
69
+ self._set_state(transition.new_intermediate)
70
+
71
+ try:
72
+ controlled_fn()
73
+ except Exception:
74
+ self._set_state(transition.new_failed)
75
+ raise
76
+
77
+ self._set_state(transition.new_succeeded)
78
+
79
+ if post_listener_fn is not None:
80
+ for listener in self._listeners:
81
+ post_listener_fn(listener)(self._controlled)
79
82
 
80
83
  ##
81
84
 
82
85
  @ta.override
83
- def lifecycle_construct(self) -> R | None:
84
- return self._advance(
86
+ def lifecycle_construct(self) -> None:
87
+ self._advance(
85
88
  LifecycleTransitions.CONSTRUCT,
86
- self._lifecycle.lifecycle_construct,
89
+ self._controlled.lifecycle_construct,
87
90
  )
88
91
 
89
92
  @ta.override
90
- def lifecycle_start(self) -> R | None:
91
- return self._advance(
93
+ def lifecycle_start(self) -> None:
94
+ self._advance(
92
95
  LifecycleTransitions.START,
93
- self._lifecycle.lifecycle_start,
96
+ self._controlled.lifecycle_start,
94
97
  lambda l: l.on_starting,
95
98
  lambda l: l.on_started,
96
99
  )
97
100
 
98
101
  @ta.override
99
- def lifecycle_stop(self) -> R | None:
100
- return self._advance(
102
+ def lifecycle_stop(self) -> None:
103
+ self._advance(
101
104
  LifecycleTransitions.STOP,
102
- self._lifecycle.lifecycle_stop,
105
+ self._controlled.lifecycle_stop,
103
106
  lambda l: l.on_stopping,
104
107
  lambda l: l.on_stopped,
105
108
  )
106
109
 
107
110
  @ta.override
108
- def lifecycle_destroy(self) -> R | None:
109
- return self._advance(
111
+ def lifecycle_destroy(self) -> None:
112
+ self._advance(
110
113
  LifecycleTransitions.DESTROY,
111
- self._lifecycle.lifecycle_destroy,
114
+ self._controlled.lifecycle_destroy,
112
115
  )
113
116
 
114
117
 
115
- ##
116
-
117
-
118
- LifecycleListener: ta.TypeAlias = AnyLifecycleListener[LifecycleT, None]
118
+ #
119
119
 
120
120
 
121
- class LifecycleController(
122
- AnyLifecycleController[LifecycleT, None],
123
- Lifecycle,
124
- ta.Generic[LifecycleT],
125
- ):
121
+ @ta.final
122
+ class AsyncLifecycleController(AsyncLifecycle, lang.Final):
126
123
  def __init__(
127
124
  self,
128
- lifecycle: LifecycleT,
125
+ controlled: AsyncLifecycle,
129
126
  *,
130
- lock: lang.DefaultLockable = None,
127
+ lock: lang.DefaultAsyncLockable = None,
131
128
  ) -> None:
132
- super().__init__(lifecycle)
129
+ super().__init__()
133
130
 
134
- self._lock = lang.default_lock(lock, False)
131
+ self._controlled: AsyncLifecycle = check.isinstance(controlled, AsyncLifecycle)
132
+ self._lock = lang.default_async_lock(lock, None)
135
133
 
136
- def _advance(
134
+ self._state = LifecycleStates.NEW
135
+ self._listeners: list[AsyncLifecycleListener] = []
136
+
137
+ __repr__ = lang.attr_ops(lambda o: (o.controlled, o.state)).repr
138
+
139
+ #
140
+
141
+ @property
142
+ def controlled(self) -> AsyncLifecycle:
143
+ return self._controlled
144
+
145
+ @property
146
+ def state(self) -> LifecycleState:
147
+ return self._state
148
+
149
+ def add_listener(self, listener: AsyncLifecycleListener) -> ta.Self:
150
+ self._listeners.append(check.isinstance(listener, AsyncLifecycleListener))
151
+ return self
152
+
153
+ #
154
+
155
+ async def _set_state(self, state: LifecycleState) -> None:
156
+ self._state = state
157
+ await self._controlled.lifecycle_state(state)
158
+
159
+ async def _advance(
137
160
  self,
138
161
  transition: LifecycleTransition,
139
- lifecycle_fn: ta.Callable[[], None],
140
- pre_listener_fn: ta.Callable[
141
- [LifecycleListener[LifecycleT]],
142
- ta.Callable[[LifecycleT], None],
143
- ] | None = None,
144
- post_listener_fn: ta.Callable[
145
- [LifecycleListener[LifecycleT]],
146
- ta.Callable[[LifecycleT], None],
147
- ] | None = None,
162
+ controlled_fn: ta.Callable[[], ta.Awaitable[None]],
163
+ pre_listener_fn: ta.Callable[[AsyncLifecycleListener], ta.Callable[[AsyncLifecycle], ta.Awaitable[None]]] | None = None, # noqa
164
+ post_listener_fn: ta.Callable[[AsyncLifecycleListener], ta.Callable[[AsyncLifecycle], ta.Awaitable[None]]] | None = None, # noqa
148
165
  ) -> None:
149
- with self._lock():
166
+ async with self._lock():
150
167
  if pre_listener_fn is not None:
151
168
  for listener in self._listeners:
152
- pre_listener_fn(listener)(self._lifecycle)
169
+ await pre_listener_fn(listener)(self._controlled)
170
+
153
171
  check.state(self._state in transition.old)
154
- self._state = transition.new_intermediate
172
+ await self._set_state(transition.new_intermediate)
173
+
155
174
  try:
156
- lifecycle_fn()
175
+ await controlled_fn()
157
176
  except Exception:
158
- self._state = transition.new_failed
177
+ await self._set_state(transition.new_failed)
159
178
  raise
160
- self._state = transition.new_succeeded
179
+
180
+ await self._set_state(transition.new_succeeded)
181
+
161
182
  if post_listener_fn is not None:
162
183
  for listener in self._listeners:
163
- post_listener_fn(listener)(self._lifecycle)
184
+ await post_listener_fn(listener)(self._controlled)
185
+
186
+ ##
187
+
188
+ @ta.override
189
+ async def lifecycle_construct(self) -> None:
190
+ await self._advance(
191
+ LifecycleTransitions.CONSTRUCT,
192
+ self._controlled.lifecycle_construct,
193
+ )
194
+
195
+ @ta.override
196
+ async def lifecycle_start(self) -> None:
197
+ await self._advance(
198
+ LifecycleTransitions.START,
199
+ self._controlled.lifecycle_start,
200
+ lambda l: l.on_starting,
201
+ lambda l: l.on_started,
202
+ )
203
+
204
+ @ta.override
205
+ async def lifecycle_stop(self) -> None:
206
+ await self._advance(
207
+ LifecycleTransitions.STOP,
208
+ self._controlled.lifecycle_stop,
209
+ lambda l: l.on_stopping,
210
+ lambda l: l.on_stopped,
211
+ )
212
+
213
+ @ta.override
214
+ async def lifecycle_destroy(self) -> None:
215
+ await self._advance(
216
+ LifecycleTransitions.DESTROY,
217
+ self._controlled.lifecycle_destroy,
218
+ )
219
+
220
+
221
+ #
222
+
223
+
224
+ AnyLifecycleController: ta.TypeAlias = LifecycleController | AsyncLifecycleController
225
+
226
+ ANY_LIFECYCLE_CONTROLLER_TYPES: tuple[type[LifecycleController | AsyncLifecycleController], ...] = (LifecycleController, AsyncLifecycleController) # noqa
@@ -0,0 +1,143 @@
1
+ import contextlib
2
+ import typing as ta
3
+
4
+ from .. import check
5
+ from .. import collections as col
6
+ from .. import dataclasses as dc
7
+ from .. import inject as inj
8
+ from .. import lang
9
+ from .base import AsyncLifecycle
10
+ from .base import Lifecycle
11
+ from .contextmanagers import async_lifecycle_context_manage
12
+ from .contextmanagers import lifecycle_context_manage
13
+ from .manager import AsyncLifecycleManager
14
+ from .manager import LifecycleManager
15
+ from .unwrap import unwrap_any_lifecycle
16
+
17
+
18
+ ##
19
+
20
+
21
+ @ta.final
22
+ class _LifecycleRegistrar(lang.Final):
23
+ def __init__(
24
+ self,
25
+ lifecycle_manager_cls: type[LifecycleManager | AsyncLifecycleManager],
26
+ lifecycle_cls_tup: tuple[type[Lifecycle | AsyncLifecycle], ...],
27
+ *,
28
+ unwrap: bool = False,
29
+ ) -> None:
30
+ super().__init__()
31
+
32
+ self._lifecycle_manager_cls = lifecycle_manager_cls
33
+ self._lifecycle_cls_tup = lifecycle_cls_tup
34
+ self._unwrap = unwrap
35
+
36
+ self._seen: ta.MutableSet[ta.Any] = col.IdentityWeakSet()
37
+ self._stack: list[_LifecycleRegistrar.State] = []
38
+
39
+ @ta.final
40
+ @dc.dataclass(frozen=True)
41
+ class Dep(lang.Final):
42
+ binding: inj.Binding | None
43
+ obj: ta.Any
44
+ lco: ta.Any
45
+
46
+ @ta.final
47
+ @dc.dataclass(frozen=True)
48
+ class State(lang.Final):
49
+ key: inj.Key
50
+ deps: list['_LifecycleRegistrar.Dep'] = dc.field(default_factory=list)
51
+
52
+ async def _on_provision(
53
+ self,
54
+ injector: inj.AsyncInjector,
55
+ key: inj.Key,
56
+ binding: inj.Binding | None,
57
+ fn: ta.Callable[[], ta.Awaitable[ta.Any]],
58
+ ) -> ta.Awaitable[ta.Any]:
59
+ st = _LifecycleRegistrar.State(key)
60
+ self._stack.append(st)
61
+ try:
62
+ obj = await fn()
63
+ finally:
64
+ popped = self._stack.pop()
65
+ check.state(popped is st)
66
+
67
+ lco: ta.Any
68
+ if self._unwrap:
69
+ lco = unwrap_any_lifecycle(obj)
70
+ else:
71
+ lco = obj
72
+
73
+ if (
74
+ lco is not None and
75
+ isinstance(lco, self._lifecycle_cls_tup) and
76
+ not isinstance(obj, self._lifecycle_manager_cls)
77
+ ):
78
+ if self._stack:
79
+ self._stack[-1].deps.append(_LifecycleRegistrar.Dep(binding, obj, lco))
80
+
81
+ if obj not in self._seen:
82
+ mgr = await injector[self._lifecycle_manager_cls]
83
+
84
+ dep_lcos = [d.lco for d in st.deps]
85
+
86
+ if isinstance(mgr, AsyncLifecycleManager):
87
+ await mgr.add(lco, dep_lcos)
88
+ elif isinstance(mgr, LifecycleManager):
89
+ mgr.add(lco, dep_lcos)
90
+ else:
91
+ raise TypeError(mgr)
92
+
93
+ self._seen.add(obj)
94
+
95
+ elif self._stack:
96
+ self._stack[-1].deps.extend(st.deps)
97
+
98
+ return obj
99
+
100
+
101
+ def bind_lifecycle_registrar() -> inj.Elements:
102
+ return inj.as_elements(
103
+ inj.bind(_LifecycleRegistrar, to_const=(lr := _LifecycleRegistrar(
104
+ LifecycleManager,
105
+ (Lifecycle,),
106
+ unwrap=True,
107
+ ))),
108
+ inj.bind_provision_listener(lr._on_provision), # noqa
109
+ )
110
+
111
+
112
+ def bind_async_lifecycle_registrar() -> inj.Elements:
113
+ return inj.as_elements(
114
+ inj.bind(_LifecycleRegistrar, to_const=(lr := _LifecycleRegistrar(
115
+ AsyncLifecycleManager,
116
+ (Lifecycle, AsyncLifecycle),
117
+ unwrap=True,
118
+ ))),
119
+ inj.bind_provision_listener(lr._on_provision), # noqa
120
+ )
121
+
122
+
123
+ ##
124
+
125
+
126
+ def bind_managed_lifecycle_manager() -> inj.Elements:
127
+ # FIXME: lock?
128
+ def inner(es: contextlib.ExitStack) -> LifecycleManager:
129
+ return es.enter_context(lifecycle_context_manage(LifecycleManager()))
130
+
131
+ return inj.as_elements(
132
+ inj.bind(inner, singleton=True, eager=True),
133
+ )
134
+
135
+
136
+ def bind_async_managed_lifecycle_manager() -> inj.Elements:
137
+ # FIXME: lock?
138
+ async def inner(aes: contextlib.AsyncExitStack) -> AsyncLifecycleManager:
139
+ return await aes.enter_async_context(async_lifecycle_context_manage(AsyncLifecycleManager()))
140
+
141
+ return inj.as_elements(
142
+ inj.bind(inner, singleton=True, eager=True),
143
+ )
@@ -0,0 +1,56 @@
1
+ import typing as ta
2
+
3
+ from .. import check
4
+ from .base import AsyncLifecycle
5
+ from .base import Lifecycle
6
+
7
+
8
+ ##
9
+
10
+
11
+ class LifecycleListener:
12
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
13
+ super().__init_subclass__(**kwargs)
14
+
15
+ try:
16
+ async_lifecycle_listener_cls = AsyncLifecycleListener
17
+ except NameError:
18
+ pass
19
+ else:
20
+ check.not_issubclass(cls, async_lifecycle_listener_cls)
21
+
22
+ def on_starting(self, obj: Lifecycle) -> None:
23
+ pass
24
+
25
+ def on_started(self, obj: Lifecycle) -> None:
26
+ pass
27
+
28
+ def on_stopping(self, obj: Lifecycle) -> None:
29
+ pass
30
+
31
+ def on_stopped(self, obj: Lifecycle) -> None:
32
+ pass
33
+
34
+
35
+ class AsyncLifecycleListener:
36
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
37
+ super().__init_subclass__(**kwargs)
38
+
39
+ check.not_issubclass(cls, LifecycleListener)
40
+
41
+ async def on_starting(self, obj: AsyncLifecycle) -> None:
42
+ pass
43
+
44
+ async def on_started(self, obj: AsyncLifecycle) -> None:
45
+ pass
46
+
47
+ async def on_stopping(self, obj: AsyncLifecycle) -> None:
48
+ pass
49
+
50
+ async def on_stopped(self, obj: AsyncLifecycle) -> None:
51
+ pass
52
+
53
+
54
+ AnyLifecycleListener: ta.TypeAlias = LifecycleListener | AsyncLifecycleListener
55
+
56
+ ANY_LIFECYCLE_LISTENER_TYPES: tuple[type[LifecycleListener | AsyncLifecycleListener], ...] = (LifecycleListener, AsyncLifecycleListener) # noqa
@@ -0,0 +1,142 @@
1
+ import typing as ta
2
+
3
+ from .. import cached
4
+ from .. import check
5
+ from .. import dataclasses as dc
6
+ from .. import lang
7
+ from .base import AsyncLifecycle
8
+ from .base import Lifecycle
9
+ from .states import LifecycleState
10
+ from .states import LifecycleStates
11
+
12
+
13
+ LifecycleManagedT = ta.TypeVar('LifecycleManagedT', bound='LifecycleManaged')
14
+
15
+ AsyncLifecycleManagedT = ta.TypeVar('AsyncLifecycleManagedT', bound='AsyncLifecycleManaged')
16
+
17
+
18
+ ##
19
+
20
+
21
+ class LifecycleManaged(lang.Abstract):
22
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
23
+ super().__init_subclass__(**kwargs)
24
+
25
+ try:
26
+ async_lifecycle_managed_cls = AsyncLifecycleManaged
27
+ except NameError:
28
+ pass
29
+ else:
30
+ check.not_issubclass(cls, async_lifecycle_managed_cls)
31
+
32
+ @ta.final
33
+ @dc.dataclass(frozen=True)
34
+ class _Lifecycle(
35
+ Lifecycle,
36
+ lang.Final,
37
+ ta.Generic[LifecycleManagedT],
38
+ ):
39
+ obj: LifecycleManagedT
40
+
41
+ def lifecycle_state(self, state: LifecycleState) -> None:
42
+ self.obj._lifecycle_state_ = state
43
+
44
+ def lifecycle_construct(self) -> None:
45
+ self.obj._lifecycle_construct() # noqa
46
+
47
+ def lifecycle_start(self) -> None:
48
+ self.obj._lifecycle_start() # noqa
49
+
50
+ def lifecycle_stop(self) -> None:
51
+ self.obj._lifecycle_stop() # noqa
52
+
53
+ def lifecycle_destroy(self) -> None:
54
+ self.obj._lifecycle_destroy() # noqa
55
+
56
+ @ta.final
57
+ @cached.property
58
+ def _lifecycle(self) -> _Lifecycle[ta.Self]:
59
+ return LifecycleManaged._Lifecycle(self)
60
+
61
+ _lifecycle_state_: LifecycleState = LifecycleStates.NEW
62
+
63
+ @property
64
+ def _lifecycle_state(self) -> LifecycleState:
65
+ return self._lifecycle_state_
66
+
67
+ def _lifecycle_construct(self) -> None:
68
+ pass
69
+
70
+ def _lifecycle_start(self) -> None:
71
+ pass
72
+
73
+ def _lifecycle_stop(self) -> None:
74
+ pass
75
+
76
+ def _lifecycle_destroy(self) -> None:
77
+ pass
78
+
79
+
80
+ #
81
+
82
+
83
+ class AsyncLifecycleManaged(lang.Abstract):
84
+ def __init_subclass__(cls, **kwargs: ta.Any) -> None:
85
+ super().__init_subclass__(**kwargs)
86
+
87
+ check.not_issubclass(cls, LifecycleManaged)
88
+
89
+ @ta.final
90
+ @dc.dataclass(frozen=True)
91
+ class _Lifecycle(
92
+ AsyncLifecycle,
93
+ lang.Final,
94
+ ta.Generic[AsyncLifecycleManagedT],
95
+ ):
96
+ obj: AsyncLifecycleManagedT
97
+
98
+ async def lifecycle_state(self, state: LifecycleState) -> None:
99
+ self.obj._lifecycle_state_ = state
100
+
101
+ async def lifecycle_construct(self) -> None:
102
+ await self.obj._lifecycle_construct() # noqa
103
+
104
+ async def lifecycle_start(self) -> None:
105
+ await self.obj._lifecycle_start() # noqa
106
+
107
+ async def lifecycle_stop(self) -> None:
108
+ await self.obj._lifecycle_stop() # noqa
109
+
110
+ async def lifecycle_destroy(self) -> None:
111
+ await self.obj._lifecycle_destroy() # noqa
112
+
113
+ @ta.final
114
+ @cached.property
115
+ def _lifecycle(self) -> _Lifecycle[ta.Self]:
116
+ return AsyncLifecycleManaged._Lifecycle(self)
117
+
118
+ _lifecycle_state_: LifecycleState = LifecycleStates.NEW
119
+
120
+ @property
121
+ def _lifecycle_state(self) -> LifecycleState:
122
+ return self._lifecycle_state_
123
+
124
+ async def _lifecycle_construct(self) -> None:
125
+ pass
126
+
127
+ async def _lifecycle_start(self) -> None:
128
+ pass
129
+
130
+ async def _lifecycle_stop(self) -> None:
131
+ pass
132
+
133
+ async def _lifecycle_destroy(self) -> None:
134
+ pass
135
+
136
+
137
+ #
138
+
139
+
140
+ AnyLifecycleManaged: ta.TypeAlias = LifecycleManaged | AsyncLifecycleManaged
141
+
142
+ ANY_LIFECYCLE_MANAGED_TYPES: tuple[type[LifecycleManaged | AsyncLifecycleManaged], ...] = (LifecycleManaged, AsyncLifecycleManaged) # noqa