omlish 0.0.0.dev447__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.
- omlish/.omlish-manifests.json +12 -0
- omlish/README.md +199 -0
- omlish/__about__.py +21 -16
- omlish/argparse/all.py +17 -9
- omlish/argparse/cli.py +16 -3
- omlish/argparse/utils.py +21 -0
- omlish/asyncs/asyncio/rlock.py +110 -0
- omlish/asyncs/asyncio/sync.py +43 -0
- omlish/asyncs/asyncio/utils.py +2 -0
- omlish/asyncs/sync.py +25 -0
- omlish/bootstrap/_marshal.py +1 -1
- omlish/bootstrap/diag.py +12 -21
- omlish/bootstrap/main.py +2 -5
- omlish/bootstrap/sys.py +27 -28
- omlish/cexts/__init__.py +0 -0
- omlish/cexts/include/omlish/omlish.hh +1 -0
- omlish/collections/__init__.py +13 -1
- omlish/collections/attrregistry.py +210 -0
- omlish/collections/cache/impl.py +1 -0
- omlish/collections/identity.py +1 -0
- omlish/collections/mappings.py +28 -0
- omlish/collections/trie.py +5 -1
- omlish/collections/utils.py +77 -0
- omlish/concurrent/all.py +2 -1
- omlish/concurrent/futures.py +25 -0
- omlish/concurrent/threadlets.py +1 -1
- omlish/daemons/reparent.py +2 -3
- omlish/daemons/spawning.py +2 -3
- omlish/dataclasses/__init__.py +2 -0
- omlish/dataclasses/impl/api/classes/decorator.py +3 -0
- omlish/dataclasses/impl/api/classes/make.py +3 -0
- omlish/dataclasses/impl/concerns/repr.py +15 -2
- omlish/dataclasses/impl/configs.py +97 -37
- omlish/dataclasses/impl/generation/compilation.py +21 -19
- omlish/dataclasses/impl/generation/globals.py +1 -0
- omlish/dataclasses/impl/generation/ops.py +1 -0
- omlish/dataclasses/impl/generation/plans.py +2 -17
- omlish/dataclasses/impl/generation/processor.py +106 -25
- omlish/dataclasses/impl/processing/base.py +8 -0
- omlish/dataclasses/impl/processing/driving.py +19 -7
- omlish/dataclasses/specs.py +1 -0
- omlish/dataclasses/tools/modifiers.py +5 -0
- omlish/diag/_pycharm/runhack.py +1 -1
- omlish/diag/cmds/__init__.py +0 -0
- omlish/diag/{lslocks.py → cmds/lslocks.py} +6 -6
- omlish/diag/{lsof.py → cmds/lsof.py} +6 -6
- omlish/diag/{ps.py → cmds/ps.py} +6 -6
- omlish/diag/pycharm.py +16 -2
- omlish/diag/pydevd.py +58 -40
- omlish/diag/replserver/console.py +1 -1
- omlish/dispatch/__init__.py +18 -12
- omlish/dispatch/methods.py +50 -140
- omlish/dom/rendering.py +1 -1
- omlish/formats/dotenv.py +1 -1
- omlish/formats/json/stream/__init__.py +13 -0
- omlish/funcs/guard.py +225 -0
- omlish/graphs/dot/rendering.py +1 -1
- omlish/http/all.py +44 -4
- omlish/http/clients/asyncs.py +33 -27
- omlish/http/clients/base.py +17 -1
- omlish/http/clients/coro/__init__.py +0 -0
- omlish/http/clients/coro/sync.py +171 -0
- omlish/http/clients/default.py +208 -29
- omlish/http/clients/executor.py +56 -0
- omlish/http/clients/httpx.py +72 -11
- omlish/http/clients/middleware.py +181 -0
- omlish/http/clients/sync.py +33 -27
- omlish/http/clients/syncasync.py +49 -0
- omlish/http/clients/urllib.py +6 -3
- omlish/http/coro/client/connection.py +15 -6
- omlish/http/coro/io.py +2 -0
- omlish/http/flasky/__init__.py +40 -0
- omlish/http/flasky/_compat.py +2 -0
- omlish/http/flasky/api.py +82 -0
- omlish/http/flasky/app.py +203 -0
- omlish/http/flasky/cvs.py +59 -0
- omlish/http/flasky/requests.py +20 -0
- omlish/http/flasky/responses.py +23 -0
- omlish/http/flasky/routes.py +23 -0
- omlish/http/flasky/types.py +15 -0
- omlish/http/urls.py +67 -0
- omlish/inject/__init__.py +57 -29
- omlish/inject/_dataclasses.py +5148 -0
- omlish/inject/binder.py +11 -52
- omlish/inject/eagers.py +2 -0
- omlish/inject/elements.py +27 -0
- omlish/inject/helpers/__init__.py +0 -0
- omlish/inject/{utils.py → helpers/constfn.py} +3 -3
- omlish/inject/{tags.py → helpers/id.py} +2 -2
- omlish/inject/helpers/late.py +76 -0
- omlish/inject/{managed.py → helpers/managed.py} +10 -10
- omlish/inject/helpers/multis.py +143 -0
- omlish/inject/helpers/wrappers.py +54 -0
- omlish/inject/impl/elements.py +54 -21
- omlish/inject/impl/injector.py +29 -25
- omlish/inject/impl/inspect.py +10 -1
- omlish/inject/impl/maysync.py +3 -4
- omlish/inject/impl/multis.py +3 -0
- omlish/inject/impl/sync.py +3 -4
- omlish/inject/injector.py +31 -2
- omlish/inject/inspect.py +35 -0
- omlish/inject/maysync.py +2 -4
- omlish/inject/multis.py +8 -0
- omlish/inject/overrides.py +3 -3
- omlish/inject/privates.py +6 -0
- omlish/inject/providers.py +3 -2
- omlish/inject/sync.py +5 -4
- omlish/io/buffers.py +118 -0
- omlish/io/readers.py +29 -0
- omlish/iterators/transforms.py +2 -2
- omlish/lang/__init__.py +180 -97
- omlish/lang/_asyncs.cc +186 -0
- omlish/lang/asyncs.py +17 -0
- omlish/lang/casing.py +11 -0
- omlish/lang/contextmanagers.py +28 -4
- omlish/lang/functions.py +31 -22
- omlish/lang/imports/_capture.cc +11 -9
- omlish/lang/imports/capture.py +363 -170
- omlish/lang/imports/proxy.py +455 -152
- omlish/lang/lazyglobals.py +22 -9
- omlish/lang/params.py +17 -0
- omlish/lang/recursion.py +0 -1
- omlish/lang/sequences.py +124 -0
- omlish/lifecycles/README.md +30 -0
- omlish/lifecycles/__init__.py +87 -13
- omlish/lifecycles/_dataclasses.py +1388 -0
- omlish/lifecycles/base.py +178 -64
- omlish/lifecycles/contextmanagers.py +113 -4
- omlish/lifecycles/controller.py +150 -87
- omlish/lifecycles/injection.py +143 -0
- omlish/lifecycles/listeners.py +56 -0
- omlish/lifecycles/managed.py +142 -0
- omlish/lifecycles/manager.py +218 -93
- omlish/lifecycles/states.py +2 -0
- omlish/lifecycles/transitions.py +3 -0
- omlish/lifecycles/unwrap.py +57 -0
- omlish/lite/abstract.py +54 -24
- omlish/lite/asyncs.py +2 -2
- omlish/lite/attrops.py +2 -0
- omlish/lite/contextmanagers.py +4 -4
- omlish/lite/dataclasses.py +44 -0
- omlish/lite/maybes.py +8 -0
- omlish/lite/maysync.py +1 -5
- omlish/lite/pycharm.py +1 -1
- omlish/lite/typing.py +24 -0
- omlish/logs/_amalg.py +1 -1
- omlish/logs/all.py +25 -11
- omlish/logs/asyncs.py +73 -0
- omlish/logs/base.py +101 -12
- omlish/logs/contexts.py +4 -1
- omlish/logs/lists.py +125 -0
- omlish/logs/modules.py +19 -1
- omlish/logs/std/loggers.py +6 -1
- omlish/logs/std/noisy.py +11 -9
- omlish/logs/{standard.py → std/standard.py} +3 -4
- omlish/logs/utils.py +17 -2
- omlish/manifests/loading.py +2 -1
- omlish/marshal/__init__.py +33 -13
- omlish/marshal/_dataclasses.py +2774 -0
- omlish/marshal/base/configs.py +12 -0
- omlish/marshal/base/contexts.py +36 -21
- omlish/marshal/base/funcs.py +8 -11
- omlish/marshal/base/options.py +8 -0
- omlish/marshal/base/registries.py +146 -44
- omlish/marshal/base/types.py +40 -16
- omlish/marshal/composite/iterables.py +33 -20
- omlish/marshal/composite/literals.py +20 -18
- omlish/marshal/composite/mappings.py +36 -23
- omlish/marshal/composite/maybes.py +29 -19
- omlish/marshal/composite/newtypes.py +16 -16
- omlish/marshal/composite/optionals.py +14 -14
- omlish/marshal/composite/special.py +15 -15
- omlish/marshal/composite/unions/__init__.py +0 -0
- omlish/marshal/composite/unions/literals.py +93 -0
- omlish/marshal/composite/unions/primitives.py +103 -0
- omlish/marshal/factories/invalidate.py +18 -68
- omlish/marshal/factories/method.py +26 -0
- omlish/marshal/factories/moduleimport/factories.py +22 -65
- omlish/marshal/factories/multi.py +13 -25
- omlish/marshal/factories/recursive.py +42 -56
- omlish/marshal/factories/typecache.py +29 -74
- omlish/marshal/factories/typemap.py +42 -43
- omlish/marshal/objects/dataclasses.py +129 -106
- omlish/marshal/objects/marshal.py +18 -14
- omlish/marshal/objects/namedtuples.py +48 -42
- omlish/marshal/objects/unmarshal.py +19 -15
- omlish/marshal/polymorphism/marshal.py +9 -11
- omlish/marshal/polymorphism/metadata.py +16 -5
- omlish/marshal/polymorphism/standard.py +13 -1
- omlish/marshal/polymorphism/unions.py +15 -105
- omlish/marshal/polymorphism/unmarshal.py +9 -10
- omlish/marshal/singular/enums.py +14 -18
- omlish/marshal/standard.py +10 -6
- omlish/marshal/trivial/any.py +1 -1
- omlish/marshal/trivial/forbidden.py +21 -26
- omlish/metadata.py +23 -1
- omlish/os/forkhooks.py +4 -0
- omlish/os/pidfiles/pinning.py +2 -2
- omlish/reflect/__init__.py +43 -26
- omlish/reflect/ops.py +10 -1
- omlish/reflect/types.py +1 -0
- omlish/secrets/marshal.py +1 -1
- omlish/specs/jmespath/__init__.py +12 -3
- omlish/specs/jmespath/_dataclasses.py +2893 -0
- omlish/specs/jmespath/ast.py +1 -1
- omlish/specs/jsonrpc/__init__.py +13 -0
- omlish/specs/jsonrpc/_marshal.py +32 -23
- omlish/specs/jsonrpc/conns.py +10 -7
- omlish/specs/jsonschema/_marshal.py +1 -1
- omlish/specs/jsonschema/keywords/__init__.py +7 -0
- omlish/specs/jsonschema/keywords/_dataclasses.py +1644 -0
- omlish/specs/openapi/_marshal.py +31 -22
- omlish/sql/__init__.py +24 -5
- omlish/sql/{tabledefs/alchemy.py → alchemy/tabledefs.py} +2 -2
- omlish/sql/api/dbapi.py +1 -1
- omlish/sql/dbapi/__init__.py +15 -0
- omlish/sql/{dbapi.py → dbapi/drivers.py} +2 -2
- omlish/sql/queries/__init__.py +3 -0
- omlish/sql/queries/_marshal.py +2 -2
- omlish/sql/queries/rendering.py +1 -1
- omlish/sql/tabledefs/_marshal.py +1 -1
- omlish/subprocesses/base.py +4 -0
- omlish/subprocesses/editor.py +1 -1
- omlish/sync.py +155 -21
- omlish/term/alt.py +60 -0
- omlish/term/confirm.py +8 -8
- omlish/term/pager.py +235 -0
- omlish/term/terminfo.py +935 -0
- omlish/term/termstate.py +67 -0
- omlish/term/vt100/terminal.py +0 -3
- omlish/testing/pytest/plugins/asyncs/fixtures.py +4 -1
- omlish/testing/pytest/plugins/asyncs/plugin.py +2 -0
- omlish/testing/pytest/plugins/skips.py +2 -1
- omlish/testing/unittest/main.py +3 -3
- omlish/text/docwrap/__init__.py +3 -0
- omlish/text/docwrap/__main__.py +11 -0
- omlish/text/docwrap/api.py +83 -0
- omlish/text/docwrap/cli.py +91 -0
- omlish/text/docwrap/groups.py +84 -0
- omlish/text/docwrap/lists.py +167 -0
- omlish/text/docwrap/parts.py +146 -0
- omlish/text/docwrap/reflowing.py +106 -0
- omlish/text/docwrap/rendering.py +151 -0
- omlish/text/docwrap/utils.py +11 -0
- omlish/text/docwrap/wrapping.py +59 -0
- omlish/text/filecache.py +2 -2
- omlish/text/lorem.py +6 -0
- omlish/text/parts.py +2 -2
- omlish/text/textwrap.py +51 -0
- omlish/typedvalues/marshal.py +85 -59
- omlish/typedvalues/values.py +2 -1
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/METADATA +36 -32
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/RECORD +260 -199
- omlish/dataclasses/impl/generation/mangling.py +0 -18
- omlish/funcs/match.py +0 -227
- omlish/lifecycles/abstract.py +0 -86
- omlish/marshal/factories/match.py +0 -34
- omlish/marshal/factories/simple.py +0 -28
- /omlish/inject/{impl → helpers}/proxy.py +0 -0
- /omlish/inject/impl/{providers2.py → providersmap.py} +0 -0
- /omlish/sql/{abc.py → dbapi/abc.py} +0 -0
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev447.dist-info → omlish-0.0.0.dev493.dist-info}/top_level.txt +0 -0
omlish/lang/lazyglobals.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import threading
|
|
1
2
|
import typing as ta
|
|
2
3
|
|
|
3
4
|
|
|
@@ -15,6 +16,10 @@ class AmbiguousLazyGlobalsFallbackError(Exception):
|
|
|
15
16
|
return f'{self.__class__.__name__}({self.attr!r}, {self.fallbacks!r})'
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
_LAZY_GLOBALS_LOCK = threading.RLock()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@ta.final
|
|
18
23
|
class LazyGlobals:
|
|
19
24
|
def __init__(
|
|
20
25
|
self,
|
|
@@ -22,8 +27,6 @@ class LazyGlobals:
|
|
|
22
27
|
globals: ta.MutableMapping[str, ta.Any] | None = None, # noqa
|
|
23
28
|
update_globals: bool = False,
|
|
24
29
|
) -> None:
|
|
25
|
-
super().__init__()
|
|
26
|
-
|
|
27
30
|
self._globals = globals
|
|
28
31
|
self._update_globals = update_globals
|
|
29
32
|
|
|
@@ -37,18 +40,28 @@ class LazyGlobals:
|
|
|
37
40
|
except KeyError:
|
|
38
41
|
pass
|
|
39
42
|
else:
|
|
40
|
-
if not
|
|
43
|
+
if xga.__class__ is not cls:
|
|
41
44
|
raise RuntimeError(f'Module already has __getattr__ hook: {xga}') # noqa
|
|
42
45
|
return xga
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
with _LAZY_GLOBALS_LOCK:
|
|
48
|
+
try:
|
|
49
|
+
xga = globals['__getattr__']
|
|
50
|
+
except KeyError:
|
|
51
|
+
pass
|
|
52
|
+
else:
|
|
53
|
+
if xga.__class__ is not cls:
|
|
54
|
+
raise RuntimeError(f'Module already has __getattr__ hook: {xga}') # noqa
|
|
55
|
+
return xga
|
|
56
|
+
|
|
57
|
+
lm = cls(
|
|
58
|
+
globals=globals,
|
|
59
|
+
update_globals=True,
|
|
60
|
+
)
|
|
48
61
|
|
|
49
|
-
|
|
62
|
+
globals['__getattr__'] = lm
|
|
50
63
|
|
|
51
|
-
|
|
64
|
+
return lm
|
|
52
65
|
|
|
53
66
|
def set_fn(self, attr: str, fn: ta.Callable[[], ta.Any]) -> 'LazyGlobals':
|
|
54
67
|
self._attr_fns[attr] = fn
|
omlish/lang/params.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
3
|
- check validity
|
|
4
|
+
- signature vs getfullargspec - diff unwrapping + 'self' handling
|
|
4
5
|
"""
|
|
5
6
|
import dataclasses as dc
|
|
6
7
|
import enum
|
|
@@ -16,6 +17,13 @@ from .classes.restrict import Sealed
|
|
|
16
17
|
T = ta.TypeVar('T')
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
CanParamSpec: ta.TypeAlias = ta.Union[
|
|
21
|
+
'ParamSpec',
|
|
22
|
+
inspect.Signature,
|
|
23
|
+
ta.Callable,
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
|
|
19
27
|
##
|
|
20
28
|
|
|
21
29
|
|
|
@@ -101,6 +109,15 @@ class ParamSpec(ta.Sequence[Param], Final):
|
|
|
101
109
|
|
|
102
110
|
#
|
|
103
111
|
|
|
112
|
+
@classmethod
|
|
113
|
+
def of(cls, obj: CanParamSpec) -> 'ParamSpec':
|
|
114
|
+
if isinstance(obj, ParamSpec):
|
|
115
|
+
return obj
|
|
116
|
+
elif isinstance(obj, inspect.Signature):
|
|
117
|
+
return cls.of_signature(obj)
|
|
118
|
+
else:
|
|
119
|
+
return cls.inspect(obj)
|
|
120
|
+
|
|
104
121
|
@classmethod
|
|
105
122
|
def of_signature(
|
|
106
123
|
cls,
|
omlish/lang/recursion.py
CHANGED
omlish/lang/sequences.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- StrView, BytesView - in lieu of hkt lol
|
|
4
|
+
- cext? even necessary?
|
|
5
|
+
- __eq__, cmp, __hash__
|
|
6
|
+
- __buffer__
|
|
7
|
+
- optimize `slice(None)`, keep as SeqView but fast path ops
|
|
8
|
+
- shorter repr if __len__ > some threshold
|
|
9
|
+
- use materialize()?
|
|
10
|
+
"""
|
|
11
|
+
import typing as ta
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
T = ta.TypeVar('T')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
##
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def iterslice(
|
|
21
|
+
seq: ta.Sequence[T],
|
|
22
|
+
slc: slice,
|
|
23
|
+
) -> ta.Iterator[T]:
|
|
24
|
+
return map(seq.__getitem__, range(*slc.indices(len(seq))))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def iterrange(
|
|
28
|
+
seq: ta.Sequence[T],
|
|
29
|
+
start: int | None = None,
|
|
30
|
+
stop: int | None = None,
|
|
31
|
+
step: int | None = None,
|
|
32
|
+
) -> ta.Iterator[T]:
|
|
33
|
+
return iterslice(seq, slice(start, stop, step))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@ta.final
|
|
40
|
+
class SeqView(ta.Sequence[T]):
|
|
41
|
+
def __init__(self, data: ta.Sequence[T], slice_: slice = slice(None)) -> None:
|
|
42
|
+
if data.__class__ is SeqView:
|
|
43
|
+
self._data = data._data # type: ignore[attr-defined] # noqa
|
|
44
|
+
self._range = data._range[slice_] # type: ignore[attr-defined] # noqa
|
|
45
|
+
else:
|
|
46
|
+
self._data = data
|
|
47
|
+
self._range = range(*slice_.indices(len(data)))
|
|
48
|
+
|
|
49
|
+
def __init_subclass__(cls, **kwargs):
|
|
50
|
+
raise TypeError
|
|
51
|
+
|
|
52
|
+
_data: ta.Sequence[T]
|
|
53
|
+
_range: range
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def _from_range(cls, base: ta.Sequence[T], rng: range) -> 'SeqView[T]':
|
|
57
|
+
self = object.__new__(cls)
|
|
58
|
+
self._data = base
|
|
59
|
+
self._range = rng
|
|
60
|
+
return self
|
|
61
|
+
|
|
62
|
+
def __repr__(self) -> str:
|
|
63
|
+
return f'{self.__class__.__name__}({self._data!r}, {self.slice!r})'
|
|
64
|
+
|
|
65
|
+
#
|
|
66
|
+
|
|
67
|
+
def __len__(self) -> int:
|
|
68
|
+
return len(self._range)
|
|
69
|
+
|
|
70
|
+
def __getitem__(self, key: int | slice) -> ta.Union[T, 'SeqView[T]']: # type: ignore[override]
|
|
71
|
+
if isinstance(key, slice):
|
|
72
|
+
nr = self._range[key]
|
|
73
|
+
return SeqView._from_range(self._data, nr)
|
|
74
|
+
return self._data[self._range[key]]
|
|
75
|
+
|
|
76
|
+
def __iter__(self) -> ta.Iterator[T]:
|
|
77
|
+
return map(self._data.__getitem__, self._range)
|
|
78
|
+
|
|
79
|
+
def __reversed__(self) -> ta.Iterator[T]:
|
|
80
|
+
return map(self._data.__getitem__, reversed(self._range))
|
|
81
|
+
|
|
82
|
+
def count(self, value: ta.Any) -> int:
|
|
83
|
+
c = 0
|
|
84
|
+
for i in self._range:
|
|
85
|
+
if self._data[i] == value:
|
|
86
|
+
c += 1
|
|
87
|
+
return c
|
|
88
|
+
|
|
89
|
+
def index(self, value: ta.Any, start: int = 0, stop: int | None = None) -> int:
|
|
90
|
+
sub = self._range[slice(start, stop, 1)]
|
|
91
|
+
for off, i in enumerate(sub):
|
|
92
|
+
if self._data[i] == value:
|
|
93
|
+
return off
|
|
94
|
+
raise ValueError(f'{value!r} is not in view')
|
|
95
|
+
|
|
96
|
+
#
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def data(self) -> ta.Sequence[T]:
|
|
100
|
+
return self._data
|
|
101
|
+
|
|
102
|
+
_slice: slice
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def slice(self) -> slice:
|
|
106
|
+
try:
|
|
107
|
+
return self._slice
|
|
108
|
+
except AttributeError:
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
step = self._range.step
|
|
112
|
+
start = self._range.start
|
|
113
|
+
if len(self._range) == 0:
|
|
114
|
+
stop = start
|
|
115
|
+
else:
|
|
116
|
+
last = start + (len(self._range) - 1) * step
|
|
117
|
+
stop = last + (1 if step > 0 else -1)
|
|
118
|
+
slc = slice(start, stop, step)
|
|
119
|
+
|
|
120
|
+
self._slice = slc
|
|
121
|
+
return slc
|
|
122
|
+
|
|
123
|
+
def materialize(self) -> ta.Sequence[T]:
|
|
124
|
+
return self._data[self.slice]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Lifecycle management, inspired by [governator](https://github.com/Netflix/governator/tree/master/governator-core/).
|
|
2
|
+
|
|
3
|
+
A central idea is to 'hide the guts' of a given class's lifecycle management from code interacting with it.
|
|
4
|
+
|
|
5
|
+
The main classes are as follows:
|
|
6
|
+
|
|
7
|
+
- Lifecycle / AsyncLifecycle - the code 'managed by' the rest of the lifecycle machinery. In general, user code will
|
|
8
|
+
hide its implementations of these from the code that otherwise interacts with it. Being the lowest level / unit of
|
|
9
|
+
management callbacks, it intentionally provides no additional machinery, existing solely as a skeleton of methods
|
|
10
|
+
which will be called by lifecycle internals - this is to reduce friction with more functional / less OO code. However,
|
|
11
|
+
it still chooses to be a class with multiple nullary methods, rather than a more functional-style single unary free
|
|
12
|
+
function: the operations present in each method are generally intended to have no overlap in practice, and their
|
|
13
|
+
explicit division is a conscious choice.
|
|
14
|
+
|
|
15
|
+
- LifecycleManaged / AsyncLifecycleManaged - a mixin which can be used to add lifecycle management behavior to a class.
|
|
16
|
+
This removes the need for manual subclassing of Lifecycle / AsyncLifecycle, providing private '\_lifecycle_<state>'
|
|
17
|
+
callback methods (with default no-op implementations) which subclasses may override.
|
|
18
|
+
|
|
19
|
+
- LifecycleListener / AsyncLifecycleListener - callback interfaces whose methods will be called when a lifecycle object
|
|
20
|
+
goes through a lifecycle state transition.
|
|
21
|
+
|
|
22
|
+
- LifecycleController / AsyncLifecycleController - these classes run the state machine for any single Lifecycle /
|
|
23
|
+
AsyncLifecycle instance. They are also responsible for maintaining a registry of lifecycle listeners and calling their
|
|
24
|
+
methods as necessary. Unlike user code, these classes are openly subclasses of Lifecycle / AsyncLifecycle, allowing
|
|
25
|
+
them to be called as application state dictates - they will internally ensure correct state transitions.
|
|
26
|
+
|
|
27
|
+
- LifecycleManager / AsyncLifecycleManager - these classes are responsible for construction and operation of (acyclic)
|
|
28
|
+
graphs of lifecycle objects. They will ensure that, as necessary according to registered dependencies, lifecycle
|
|
29
|
+
objects are started in the correct order, and that they are stopped in the correct order. This class is itself a
|
|
30
|
+
LifecycleManaged / AsyncLifecycleManaged. Notably, AsyncLifecycleManager can also manage sync Lifecycles.
|
omlish/lifecycles/__init__.py
CHANGED
|
@@ -1,43 +1,71 @@
|
|
|
1
|
-
from
|
|
2
|
-
AbstractLifecycle,
|
|
1
|
+
from .. import dataclasses as _dc
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
|
|
4
|
+
_dc.init_package(
|
|
5
|
+
globals(),
|
|
6
|
+
codegen=True,
|
|
5
7
|
)
|
|
6
8
|
|
|
9
|
+
|
|
10
|
+
##
|
|
11
|
+
|
|
12
|
+
|
|
7
13
|
from .base import ( # noqa
|
|
8
|
-
|
|
14
|
+
Lifecycle,
|
|
15
|
+
AsyncLifecycle,
|
|
9
16
|
AnyLifecycle,
|
|
10
|
-
|
|
17
|
+
ANY_LIFECYCLE_TYPES,
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
sync_to_async_lifecycle,
|
|
20
|
+
as_async_lifecycle,
|
|
21
|
+
async_to_sync_lifecycle,
|
|
22
|
+
as_sync_lifecycle,
|
|
15
23
|
|
|
16
|
-
|
|
24
|
+
CallbackLifecycle,
|
|
17
25
|
CallbackAsyncLifecycle,
|
|
18
|
-
AsyncLifecycle,
|
|
19
26
|
)
|
|
20
27
|
|
|
21
28
|
from .contextmanagers import ( # noqa
|
|
22
29
|
ContextManagerLifecycle,
|
|
30
|
+
AsyncContextManagerLifecycle,
|
|
31
|
+
|
|
23
32
|
LifecycleContextManager,
|
|
33
|
+
AsyncLifecycleContextManager,
|
|
34
|
+
|
|
35
|
+
lifecycle_context_manage,
|
|
36
|
+
async_lifecycle_context_manage,
|
|
24
37
|
)
|
|
25
38
|
|
|
26
39
|
from .controller import ( # noqa
|
|
27
|
-
|
|
40
|
+
LifecycleController,
|
|
41
|
+
AsyncLifecycleController,
|
|
28
42
|
AnyLifecycleController,
|
|
43
|
+
ANY_LIFECYCLE_CONTROLLER_TYPES,
|
|
44
|
+
)
|
|
29
45
|
|
|
30
|
-
|
|
46
|
+
from .listeners import ( # noqa
|
|
31
47
|
LifecycleListener,
|
|
48
|
+
AsyncLifecycleListener,
|
|
49
|
+
AnyLifecycleListener,
|
|
50
|
+
ANY_LIFECYCLE_LISTENER_TYPES,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
from .managed import ( # noqa
|
|
54
|
+
LifecycleManaged,
|
|
55
|
+
AsyncLifecycleManaged,
|
|
56
|
+
AnyLifecycleManaged,
|
|
57
|
+
ANY_LIFECYCLE_MANAGED_TYPES,
|
|
32
58
|
)
|
|
33
59
|
|
|
34
60
|
from .manager import ( # noqa
|
|
61
|
+
LifecycleManagerEntry,
|
|
35
62
|
LifecycleManager,
|
|
63
|
+
AsyncLifecycleManager,
|
|
36
64
|
)
|
|
37
65
|
|
|
38
66
|
from .states import ( # noqa
|
|
39
|
-
LifecycleState,
|
|
40
67
|
LifecycleStateError,
|
|
68
|
+
LifecycleState,
|
|
41
69
|
LifecycleStates,
|
|
42
70
|
)
|
|
43
71
|
|
|
@@ -45,3 +73,49 @@ from .transitions import ( # noqa
|
|
|
45
73
|
LifecycleTransition,
|
|
46
74
|
LifecycleTransitions,
|
|
47
75
|
)
|
|
76
|
+
|
|
77
|
+
from .unwrap import ( # noqa
|
|
78
|
+
unwrap_lifecycle,
|
|
79
|
+
unwrap_async_lifecycle,
|
|
80
|
+
unwrap_any_lifecycle,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
##
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
from .. import lang as _lang # noqa
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
with _lang.auto_proxy_init(globals()):
|
|
91
|
+
##
|
|
92
|
+
|
|
93
|
+
from .injection import ( # noqa
|
|
94
|
+
bind_lifecycle_registrar,
|
|
95
|
+
bind_async_lifecycle_registrar,
|
|
96
|
+
|
|
97
|
+
bind_managed_lifecycle_manager,
|
|
98
|
+
bind_async_managed_lifecycle_manager,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
##
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
NEW = LifecycleStates.NEW
|
|
106
|
+
|
|
107
|
+
CONSTRUCTING = LifecycleStates.CONSTRUCTING
|
|
108
|
+
FAILED_CONSTRUCTING = LifecycleStates.FAILED_CONSTRUCTING
|
|
109
|
+
CONSTRUCTED = LifecycleStates.CONSTRUCTED
|
|
110
|
+
|
|
111
|
+
STARTING = LifecycleStates.STARTING
|
|
112
|
+
FAILED_STARTING = LifecycleStates.FAILED_STARTING
|
|
113
|
+
STARTED = LifecycleStates.STARTED
|
|
114
|
+
|
|
115
|
+
STOPPING = LifecycleStates.STOPPING
|
|
116
|
+
FAILED_STOPPING = LifecycleStates.FAILED_STOPPING
|
|
117
|
+
STOPPED = LifecycleStates.STOPPED
|
|
118
|
+
|
|
119
|
+
DESTROYING = LifecycleStates.DESTROYING
|
|
120
|
+
FAILED_DESTROYING = LifecycleStates.FAILED_DESTROYING
|
|
121
|
+
DESTROYED = LifecycleStates.DESTROYED
|