omlish 0.0.0.dev493__py3-none-any.whl → 0.0.0.dev506__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/CODESTYLE.md +345 -0
- omlish/README.md +2 -2
- omlish/__about__.py +6 -4
- omlish/_check.cc +209 -0
- omlish/check.py +11 -0
- omlish/dataclasses/__init__.py +4 -0
- omlish/dataclasses/impl/concerns/frozen.py +4 -1
- omlish/dataclasses/tools/replace.py +27 -0
- omlish/dispatch/functions.py +1 -1
- omlish/formats/json/stream/lexing.py +13 -5
- omlish/formats/json/stream/parsing.py +1 -1
- omlish/inject/README.md +430 -0
- omlish/inject/__init__.py +1 -0
- omlish/inject/_dataclasses.py +64 -64
- omlish/inject/eagers.py +0 -4
- omlish/inject/elements.py +4 -0
- omlish/inject/helpers/late.py +1 -1
- omlish/inject/helpers/managed.py +27 -24
- omlish/inject/impl/injector.py +7 -22
- omlish/inject/impl/inspect.py +0 -8
- omlish/inject/impl/origins.py +1 -0
- omlish/inject/impl/privates.py +2 -6
- omlish/inject/impl/providers.py +0 -4
- omlish/inject/impl/scopes.py +14 -18
- omlish/inject/inspect.py +9 -0
- omlish/inject/multis.py +0 -3
- omlish/inject/scopes.py +7 -5
- omlish/io/buffers.py +35 -8
- omlish/lang/__init__.py +8 -0
- omlish/lang/classes/simple.py +2 -1
- omlish/lang/iterables.py +6 -0
- omlish/lang/objects.py +13 -0
- omlish/lang/outcomes.py +1 -1
- omlish/lang/recursion.py +1 -1
- omlish/lang/sequences.py +33 -0
- omlish/lifecycles/_dataclasses.py +18 -18
- omlish/lifecycles/injection.py +4 -4
- omlish/lite/maybes.py +7 -0
- omlish/lite/typing.py +15 -0
- omlish/logs/all.py +11 -0
- omlish/logs/base.py +3 -3
- omlish/logs/bisync.py +99 -0
- omlish/marshal/_dataclasses.py +32 -32
- omlish/specs/jmespath/_dataclasses.py +38 -38
- omlish/specs/jsonschema/keywords/_dataclasses.py +24 -24
- omlish/typedvalues/_collection.cc +500 -0
- omlish/typedvalues/collection.py +159 -62
- omlish/typedvalues/generic.py +5 -4
- omlish/typedvalues/values.py +6 -0
- {omlish-0.0.0.dev493.dist-info → omlish-0.0.0.dev506.dist-info}/METADATA +9 -7
- {omlish-0.0.0.dev493.dist-info → omlish-0.0.0.dev506.dist-info}/RECORD +55 -50
- {omlish-0.0.0.dev493.dist-info → omlish-0.0.0.dev506.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev493.dist-info → omlish-0.0.0.dev506.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev493.dist-info → omlish-0.0.0.dev506.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev493.dist-info → omlish-0.0.0.dev506.dist-info}/top_level.txt +0 -0
omlish/inject/impl/injector.py
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
"""
|
|
2
|
-
TODO:
|
|
3
|
-
- ** can currently bind in a child/private scope shadowing an external parent binding **
|
|
4
|
-
- better source tracking
|
|
5
|
-
- scope bindings, auto in root
|
|
6
|
-
- injector-internal / blacklisted bindings (Injector itself, default scopes) without rebuilding ElementCollection
|
|
7
|
-
- config - proxies, impl select, etc
|
|
8
|
-
- config is probably shared with ElementCollection... but not 'bound', must be shared everywhere
|
|
9
|
-
- InjectorRoot object?
|
|
10
|
-
- ** eagers in any scope, on scope init/open
|
|
11
|
-
- unions - raise on ambiguous - usecase: sql.AsyncEngineLike
|
|
12
|
-
- multiple live request scopes on single injector - use private injectors?
|
|
13
|
-
- more listeners - UnboundKeyListener
|
|
14
|
-
- lazy parent listener chain cache thing
|
|
15
|
-
- https://github.com/7mind/izumi-chibi-ts
|
|
16
|
-
- Axis tagging for conditional bindings (e.g., dev vs prod implementations)
|
|
17
|
-
- Fail-fast validation with circular and missing dependency detection
|
|
18
|
-
"""
|
|
19
1
|
import contextlib
|
|
20
2
|
import functools
|
|
21
3
|
import itertools
|
|
@@ -96,6 +78,9 @@ class AsyncInjectorImpl(AsyncInjector, lang.Final):
|
|
|
96
78
|
)
|
|
97
79
|
}
|
|
98
80
|
|
|
81
|
+
if self._p is not None:
|
|
82
|
+
self._p._add_child(self) # noqa
|
|
83
|
+
|
|
99
84
|
_cs: weakref.WeakSet['AsyncInjectorImpl'] | None = None # noqa
|
|
100
85
|
|
|
101
86
|
__cur_req: ta.Optional['AsyncInjectorImpl._Request'] = None
|
|
@@ -126,8 +111,8 @@ class AsyncInjectorImpl(AsyncInjector, lang.Final):
|
|
|
126
111
|
def get_scope_impl(self, sc: Scope) -> ScopeImpl:
|
|
127
112
|
return self._scopes[sc]
|
|
128
113
|
|
|
129
|
-
def
|
|
130
|
-
c
|
|
114
|
+
def _add_child(self, c: 'AsyncInjectorImpl') -> AsyncInjector:
|
|
115
|
+
check.isinstance(c, AsyncInjectorImpl)
|
|
131
116
|
if self._cs is None:
|
|
132
117
|
self._cs = weakref.WeakSet()
|
|
133
118
|
self._cs.add(c)
|
|
@@ -260,7 +245,7 @@ class AsyncInjectorImpl(AsyncInjector, lang.Final):
|
|
|
260
245
|
return obj(**kws)
|
|
261
246
|
|
|
262
247
|
|
|
263
|
-
async def create_async_injector(ce: CollectedElements) -> AsyncInjector:
|
|
264
|
-
i = AsyncInjectorImpl(ce)
|
|
248
|
+
async def create_async_injector(ce: CollectedElements, p: AsyncInjector | None = None) -> AsyncInjector:
|
|
249
|
+
i = AsyncInjectorImpl(ce, check.isinstance(p, (AsyncInjectorImpl, None)))
|
|
265
250
|
await i._init() # noqa
|
|
266
251
|
return i
|
omlish/inject/impl/inspect.py
CHANGED
omlish/inject/impl/origins.py
CHANGED
omlish/inject/impl/privates.py
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
"""
|
|
2
|
-
TODO:
|
|
3
|
-
- add origin to Id
|
|
4
|
-
"""
|
|
5
1
|
import itertools
|
|
6
2
|
import typing as ta
|
|
7
3
|
|
|
8
4
|
from ... import cached
|
|
9
|
-
from ... import check
|
|
10
5
|
from ... import dataclasses as dc
|
|
11
6
|
from ... import lang
|
|
12
7
|
from ..bindings import Binding
|
|
@@ -20,6 +15,7 @@ from ..providers import Provider
|
|
|
20
15
|
from ..scopes import Singleton
|
|
21
16
|
from .elements import ElementCollection
|
|
22
17
|
from .injector import AsyncInjectorImpl
|
|
18
|
+
from .injector import create_async_injector
|
|
23
19
|
from .providers import InternalProvider
|
|
24
20
|
from .providers import ProviderImpl
|
|
25
21
|
|
|
@@ -48,7 +44,7 @@ class PrivateInjectorProviderImpl(ProviderImpl, lang.Final):
|
|
|
48
44
|
return ()
|
|
49
45
|
|
|
50
46
|
async def provide(self, injector: AsyncInjector) -> ta.Any:
|
|
51
|
-
return
|
|
47
|
+
return await create_async_injector(self.ec, injector)
|
|
52
48
|
|
|
53
49
|
|
|
54
50
|
##
|
omlish/inject/impl/providers.py
CHANGED
omlish/inject/impl/scopes.py
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
"""
|
|
2
|
-
TODO:
|
|
3
|
-
- ContextVar ('context')
|
|
4
|
-
- greenlet?
|
|
5
|
-
- dynamic? https://github.com/wrmsr/iceworm/blob/2f6b4d5e9d237ef9665f7d57cfa6ce328efa0757/iceworm/utils/inject.py#L44
|
|
6
|
-
"""
|
|
7
1
|
import abc
|
|
8
2
|
import contextlib
|
|
9
3
|
import threading
|
|
@@ -154,18 +148,20 @@ class SeededScopeImpl(ScopeImpl):
|
|
|
154
148
|
self._ii = check.isinstance(i, _injector.AsyncInjectorImpl)
|
|
155
149
|
self._ssi = check.isinstance(self._ii.get_scope_impl(self._ss), SeededScopeImpl)
|
|
156
150
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
151
|
+
def __call__(self, seeds: ta.Mapping[Key, ta.Any]) -> ta.AsyncContextManager[None]:
|
|
152
|
+
@contextlib.asynccontextmanager
|
|
153
|
+
async def inner():
|
|
154
|
+
try:
|
|
155
|
+
if self._ssi._st is not None: # noqa
|
|
156
|
+
raise ScopeAlreadyOpenError(self._ss)
|
|
157
|
+
self._ssi._st = SeededScopeImpl.State(dict(seeds)) # noqa
|
|
158
|
+
await self._ii._instantiate_eagers(self._ss) # noqa
|
|
159
|
+
yield
|
|
160
|
+
finally:
|
|
161
|
+
if self._ssi._st is None: # noqa
|
|
162
|
+
raise ScopeNotOpenError(self._ss)
|
|
163
|
+
self._ssi._st = None # noqa
|
|
164
|
+
return inner()
|
|
169
165
|
|
|
170
166
|
def auto_elements(self) -> Elements:
|
|
171
167
|
return as_elements(
|
omlish/inject/inspect.py
CHANGED
|
@@ -68,3 +68,12 @@ def tag(obj: T, **kwargs: ta.Any) -> T:
|
|
|
68
68
|
|
|
69
69
|
def build_kwargs_target(obj: ta.Any, **kwargs: ta.Any) -> KwargsTarget:
|
|
70
70
|
return _inspect.build_kwargs_target(obj, **kwargs)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
##
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def target(**kwargs: ta.Any) -> ta.Callable[[ta.Any], KwargsTarget]:
|
|
77
|
+
def inner(obj: ta.Any) -> KwargsTarget:
|
|
78
|
+
return KwargsTarget.of(obj, **kwargs)
|
|
79
|
+
return inner
|
omlish/inject/multis.py
CHANGED
omlish/inject/scopes.py
CHANGED
|
@@ -89,14 +89,16 @@ def bind_scope_seed(k: ta.Any, ss: SeededScope) -> Element:
|
|
|
89
89
|
##
|
|
90
90
|
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
async def async_enter_seeded_scope(
|
|
92
|
+
def async_enter_seeded_scope(
|
|
94
93
|
i: '_injector.AsyncInjector',
|
|
95
94
|
ss: SeededScope,
|
|
96
95
|
keys: ta.Mapping[Key, ta.Any],
|
|
97
|
-
) -> ta.
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
) -> ta.AsyncContextManager[None]:
|
|
97
|
+
@contextlib.asynccontextmanager
|
|
98
|
+
async def inner():
|
|
99
|
+
async with (await i.provide(Key(SeededScope.Manager, tag=ss)))(keys):
|
|
100
|
+
yield
|
|
101
|
+
return inner()
|
|
100
102
|
|
|
101
103
|
|
|
102
104
|
def enter_seeded_scope(
|
omlish/io/buffers.py
CHANGED
|
@@ -190,16 +190,18 @@ class ReadableListBuffer:
|
|
|
190
190
|
super().__init__()
|
|
191
191
|
|
|
192
192
|
self._lst: list[bytes] = []
|
|
193
|
+
self._len = 0
|
|
193
194
|
|
|
194
195
|
def __bool__(self) -> ta.NoReturn:
|
|
195
196
|
raise TypeError("Use 'buf is not None' or 'len(buf)'.")
|
|
196
197
|
|
|
197
198
|
def __len__(self) -> int:
|
|
198
|
-
return
|
|
199
|
+
return self._len
|
|
199
200
|
|
|
200
201
|
def feed(self, d: bytes) -> None:
|
|
201
202
|
if d:
|
|
202
203
|
self._lst.append(d)
|
|
204
|
+
self._len += len(d)
|
|
203
205
|
|
|
204
206
|
def _chop(self, i: int, e: int) -> bytes:
|
|
205
207
|
lst = self._lst
|
|
@@ -215,6 +217,8 @@ class ReadableListBuffer:
|
|
|
215
217
|
*lst[i + 1:],
|
|
216
218
|
]
|
|
217
219
|
|
|
220
|
+
self._len -= len(o)
|
|
221
|
+
|
|
218
222
|
return o
|
|
219
223
|
|
|
220
224
|
def read(self, n: ta.Optional[int] = None) -> ta.Optional[bytes]:
|
|
@@ -224,6 +228,7 @@ class ReadableListBuffer:
|
|
|
224
228
|
|
|
225
229
|
o = b''.join(self._lst)
|
|
226
230
|
self._lst = []
|
|
231
|
+
self._len = 0
|
|
227
232
|
return o
|
|
228
233
|
|
|
229
234
|
if not (lst := self._lst):
|
|
@@ -293,7 +298,12 @@ class ReadableListBuffer:
|
|
|
293
298
|
if not (b := self._raw.read1(n)):
|
|
294
299
|
break
|
|
295
300
|
self._buf.feed(b)
|
|
296
|
-
|
|
301
|
+
|
|
302
|
+
if len(self._buf) >= n:
|
|
303
|
+
return self._buf.read(n) or b''
|
|
304
|
+
|
|
305
|
+
# EOF with a partial buffer: return what we have.
|
|
306
|
+
return self._buf.read() or b''
|
|
297
307
|
|
|
298
308
|
def readall(self) -> bytes:
|
|
299
309
|
buf = io.BytesIO()
|
|
@@ -343,7 +353,12 @@ class ReadableListBuffer:
|
|
|
343
353
|
if not (b := await self._raw.read1(n)):
|
|
344
354
|
break
|
|
345
355
|
self._buf.feed(b)
|
|
346
|
-
|
|
356
|
+
|
|
357
|
+
if len(self._buf) >= n:
|
|
358
|
+
return self._buf.read(n) or b''
|
|
359
|
+
|
|
360
|
+
# EOF with a partial buffer: return what we have.
|
|
361
|
+
return self._buf.read() or b''
|
|
347
362
|
|
|
348
363
|
async def readall(self) -> bytes:
|
|
349
364
|
buf = io.BytesIO()
|
|
@@ -396,16 +411,28 @@ class IncrementalWriteBuffer:
|
|
|
396
411
|
|
|
397
412
|
t = 0
|
|
398
413
|
for i, d in enumerate(lst): # noqa
|
|
399
|
-
|
|
414
|
+
d = check.not_empty(d)
|
|
415
|
+
n = fn(d)
|
|
400
416
|
if not n:
|
|
401
417
|
break
|
|
418
|
+
|
|
419
|
+
if n > len(d):
|
|
420
|
+
raise ValueError(n)
|
|
421
|
+
|
|
402
422
|
t += n
|
|
403
423
|
|
|
424
|
+
if n < len(d):
|
|
425
|
+
# Short write - keep the remainder of this chunk and stop.
|
|
426
|
+
self._lst = [
|
|
427
|
+
d[n:],
|
|
428
|
+
*lst[i + 1:],
|
|
429
|
+
]
|
|
430
|
+
self._pos += t
|
|
431
|
+
return t
|
|
432
|
+
|
|
404
433
|
if t:
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
*lst[i + 1:],
|
|
408
|
-
]
|
|
434
|
+
# Only fully-written chunks were consumed.
|
|
435
|
+
self._lst = lst[i + 1:]
|
|
409
436
|
self._pos += t
|
|
410
437
|
|
|
411
438
|
return t
|
omlish/lang/__init__.py
CHANGED
|
@@ -341,6 +341,7 @@ with _auto_proxy_init(globals(), update_exports=True):
|
|
|
341
341
|
ilen,
|
|
342
342
|
take,
|
|
343
343
|
consume,
|
|
344
|
+
opt_list,
|
|
344
345
|
peek,
|
|
345
346
|
chunk,
|
|
346
347
|
interleave,
|
|
@@ -381,6 +382,8 @@ with _auto_proxy_init(globals(), update_exports=True):
|
|
|
381
382
|
from .objects import ( # noqa
|
|
382
383
|
arg_repr,
|
|
383
384
|
opt_repr,
|
|
385
|
+
just_repr,
|
|
386
|
+
opt_or_just_repr,
|
|
384
387
|
|
|
385
388
|
can_weakref,
|
|
386
389
|
|
|
@@ -466,6 +469,10 @@ with _auto_proxy_init(globals(), update_exports=True):
|
|
|
466
469
|
iterslice,
|
|
467
470
|
iterrange,
|
|
468
471
|
|
|
472
|
+
seqs_all,
|
|
473
|
+
seqs_equal,
|
|
474
|
+
seqs_identical,
|
|
475
|
+
|
|
469
476
|
SeqView,
|
|
470
477
|
)
|
|
471
478
|
|
|
@@ -622,6 +629,7 @@ with _auto_proxy_init(globals(), update_exports=True):
|
|
|
622
629
|
Func3,
|
|
623
630
|
|
|
624
631
|
CachedFunc0,
|
|
632
|
+
AsyncCachedFunc0,
|
|
625
633
|
|
|
626
634
|
typing_annotations_attr,
|
|
627
635
|
)
|
omlish/lang/classes/simple.py
CHANGED
|
@@ -3,6 +3,7 @@ import functools
|
|
|
3
3
|
import threading
|
|
4
4
|
import typing as ta
|
|
5
5
|
|
|
6
|
+
from ...lite.abstract import Abstract
|
|
6
7
|
from .restrict import Final
|
|
7
8
|
from .restrict import NotInstantiable
|
|
8
9
|
|
|
@@ -40,7 +41,7 @@ class _MarkerMeta(abc.ABCMeta):
|
|
|
40
41
|
else:
|
|
41
42
|
if set(namespace) - _MARKER_NAMESPACE_KEYS:
|
|
42
43
|
raise TypeError('Markers must not include contents. Did you mean to use Namespace?')
|
|
43
|
-
if Final not in bases:
|
|
44
|
+
if Final not in bases and Abstract not in bases:
|
|
44
45
|
bases += (Final,)
|
|
45
46
|
|
|
46
47
|
return super().__new__(mcls, name, bases, namespace)
|
omlish/lang/iterables.py
CHANGED
|
@@ -26,6 +26,12 @@ def consume(it: ta.Iterable[ta.Any]) -> None:
|
|
|
26
26
|
collections.deque(it, maxlen=0)
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
def opt_list(it: ta.Iterable[T] | None) -> list[T] | None:
|
|
30
|
+
if it is None:
|
|
31
|
+
return None
|
|
32
|
+
return list(it)
|
|
33
|
+
|
|
34
|
+
|
|
29
35
|
def peek(vs: ta.Iterable[T]) -> tuple[T, ta.Iterator[T]]:
|
|
30
36
|
it = iter(vs)
|
|
31
37
|
v = next(it)
|
omlish/lang/objects.py
CHANGED
|
@@ -2,6 +2,7 @@ import types
|
|
|
2
2
|
import typing as ta
|
|
3
3
|
import weakref
|
|
4
4
|
|
|
5
|
+
from ..lite.maybes import Maybe
|
|
5
6
|
from .classes.abstract import is_abstract_class
|
|
6
7
|
|
|
7
8
|
|
|
@@ -24,6 +25,18 @@ def opt_repr(obj: ta.Any) -> str | None:
|
|
|
24
25
|
return repr(obj)
|
|
25
26
|
|
|
26
27
|
|
|
28
|
+
def just_repr(obj: Maybe) -> str | None:
|
|
29
|
+
return obj.map(repr).or_none()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def opt_or_just_repr(obj: ta.Any) -> str | None:
|
|
33
|
+
if isinstance(obj, Maybe):
|
|
34
|
+
if obj.present:
|
|
35
|
+
return repr(obj)
|
|
36
|
+
return None
|
|
37
|
+
return opt_repr(obj)
|
|
38
|
+
|
|
39
|
+
|
|
27
40
|
##
|
|
28
41
|
|
|
29
42
|
|
omlish/lang/outcomes.py
CHANGED
omlish/lang/recursion.py
CHANGED
|
@@ -65,7 +65,7 @@ def recursion_limiting_context(key: ta.Any, limit: int | None) -> ta.Iterator[in
|
|
|
65
65
|
except KeyError:
|
|
66
66
|
pd = None
|
|
67
67
|
else:
|
|
68
|
-
if not isinstance(pd, int) and pd > 0:
|
|
68
|
+
if not (isinstance(pd, int) and pd > 0):
|
|
69
69
|
raise RuntimeError
|
|
70
70
|
|
|
71
71
|
if pd is not None and pd >= limit:
|
omlish/lang/sequences.py
CHANGED
|
@@ -8,6 +8,7 @@ TODO:
|
|
|
8
8
|
- shorter repr if __len__ > some threshold
|
|
9
9
|
- use materialize()?
|
|
10
10
|
"""
|
|
11
|
+
import operator
|
|
11
12
|
import typing as ta
|
|
12
13
|
|
|
13
14
|
|
|
@@ -36,6 +37,38 @@ def iterrange(
|
|
|
36
37
|
##
|
|
37
38
|
|
|
38
39
|
|
|
40
|
+
def seqs_all(
|
|
41
|
+
fn: ta.Callable[[T, T], bool],
|
|
42
|
+
l_seq: ta.Sequence[T],
|
|
43
|
+
*r_seqs: ta.Sequence[T],
|
|
44
|
+
) -> bool:
|
|
45
|
+
if not all(len(r_seq) == len(l_seq) for r_seq in r_seqs):
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
return all(
|
|
49
|
+
fn(l, r)
|
|
50
|
+
for r_seq in r_seqs
|
|
51
|
+
for l, r in zip(l_seq, r_seq, strict=True)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def seqs_equal(
|
|
56
|
+
l_seq: ta.Sequence[T],
|
|
57
|
+
*r_seqs: ta.Sequence[T],
|
|
58
|
+
) -> bool:
|
|
59
|
+
return seqs_all(operator.eq, l_seq, *r_seqs)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def seqs_identical(
|
|
63
|
+
l_seq: ta.Sequence[T],
|
|
64
|
+
*r_seqs: ta.Sequence[T],
|
|
65
|
+
) -> bool:
|
|
66
|
+
return seqs_all(operator.is_, l_seq, *r_seqs)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
|
|
71
|
+
|
|
39
72
|
@ta.final
|
|
40
73
|
class SeqView(ta.Sequence[T]):
|
|
41
74
|
def __init__(self, data: ta.Sequence[T], slice_: slice = slice(None)) -> None:
|
|
@@ -94,7 +94,7 @@ def _process_dataclass__80a0a85b19250d1d39ff826c429bd05f9be201e1():
|
|
|
94
94
|
def __setattr__(self, name, value):
|
|
95
95
|
if (
|
|
96
96
|
type(self) is __dataclass__cls
|
|
97
|
-
|
|
97
|
+
or name in __dataclass___setattr_frozen_fields
|
|
98
98
|
):
|
|
99
99
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
100
100
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -111,7 +111,7 @@ def _process_dataclass__80a0a85b19250d1d39ff826c429bd05f9be201e1():
|
|
|
111
111
|
def __delattr__(self, name):
|
|
112
112
|
if (
|
|
113
113
|
type(self) is __dataclass__cls
|
|
114
|
-
|
|
114
|
+
or name in __dataclass___delattr_frozen_fields
|
|
115
115
|
):
|
|
116
116
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
117
117
|
super(__dataclass__cls, self).__delattr__(name)
|
|
@@ -229,7 +229,7 @@ def _process_dataclass__32f5b8178dfdf24f4db24e8d8cd63ebd10bf83f3():
|
|
|
229
229
|
def __setattr__(self, name, value):
|
|
230
230
|
if (
|
|
231
231
|
type(self) is __dataclass__cls
|
|
232
|
-
|
|
232
|
+
or name in __dataclass___setattr_frozen_fields
|
|
233
233
|
):
|
|
234
234
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
235
235
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -246,7 +246,7 @@ def _process_dataclass__32f5b8178dfdf24f4db24e8d8cd63ebd10bf83f3():
|
|
|
246
246
|
def __delattr__(self, name):
|
|
247
247
|
if (
|
|
248
248
|
type(self) is __dataclass__cls
|
|
249
|
-
|
|
249
|
+
or name in __dataclass___delattr_frozen_fields
|
|
250
250
|
):
|
|
251
251
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
252
252
|
super(__dataclass__cls, self).__delattr__(name)
|
|
@@ -408,7 +408,7 @@ def _process_dataclass__d177836dcedc950662bdf1c8a8d52e05fc91c5c7():
|
|
|
408
408
|
def __setattr__(self, name, value):
|
|
409
409
|
if (
|
|
410
410
|
type(self) is __dataclass__cls
|
|
411
|
-
|
|
411
|
+
or name in __dataclass___setattr_frozen_fields
|
|
412
412
|
):
|
|
413
413
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
414
414
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -429,7 +429,7 @@ def _process_dataclass__d177836dcedc950662bdf1c8a8d52e05fc91c5c7():
|
|
|
429
429
|
def __delattr__(self, name):
|
|
430
430
|
if (
|
|
431
431
|
type(self) is __dataclass__cls
|
|
432
|
-
|
|
432
|
+
or name in __dataclass___delattr_frozen_fields
|
|
433
433
|
):
|
|
434
434
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
435
435
|
super(__dataclass__cls, self).__delattr__(name)
|
|
@@ -567,7 +567,7 @@ def _process_dataclass__440e63ab60e5c95ef453ad0e63ffc0977bb48371():
|
|
|
567
567
|
def __setattr__(self, name, value):
|
|
568
568
|
if (
|
|
569
569
|
type(self) is __dataclass__cls
|
|
570
|
-
|
|
570
|
+
or name in __dataclass___setattr_frozen_fields
|
|
571
571
|
):
|
|
572
572
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
573
573
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -586,7 +586,7 @@ def _process_dataclass__440e63ab60e5c95ef453ad0e63ffc0977bb48371():
|
|
|
586
586
|
def __delattr__(self, name):
|
|
587
587
|
if (
|
|
588
588
|
type(self) is __dataclass__cls
|
|
589
|
-
|
|
589
|
+
or name in __dataclass___delattr_frozen_fields
|
|
590
590
|
):
|
|
591
591
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
592
592
|
super(__dataclass__cls, self).__delattr__(name)
|
|
@@ -704,7 +704,7 @@ def _process_dataclass__6c47afef6781ac6bd88758815660ccbfefe8540e():
|
|
|
704
704
|
def __setattr__(self, name, value):
|
|
705
705
|
if (
|
|
706
706
|
type(self) is __dataclass__cls
|
|
707
|
-
|
|
707
|
+
or name in __dataclass___setattr_frozen_fields
|
|
708
708
|
):
|
|
709
709
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
710
710
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -723,7 +723,7 @@ def _process_dataclass__6c47afef6781ac6bd88758815660ccbfefe8540e():
|
|
|
723
723
|
def __delattr__(self, name):
|
|
724
724
|
if (
|
|
725
725
|
type(self) is __dataclass__cls
|
|
726
|
-
|
|
726
|
+
or name in __dataclass___delattr_frozen_fields
|
|
727
727
|
):
|
|
728
728
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
729
729
|
super(__dataclass__cls, self).__delattr__(name)
|
|
@@ -863,7 +863,7 @@ def _process_dataclass__ebef99260c9b05bfd28fc9433dcc32af80493f10():
|
|
|
863
863
|
def __setattr__(self, name, value):
|
|
864
864
|
if (
|
|
865
865
|
type(self) is __dataclass__cls
|
|
866
|
-
|
|
866
|
+
or name in __dataclass___setattr_frozen_fields
|
|
867
867
|
):
|
|
868
868
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
869
869
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -883,7 +883,7 @@ def _process_dataclass__ebef99260c9b05bfd28fc9433dcc32af80493f10():
|
|
|
883
883
|
def __delattr__(self, name):
|
|
884
884
|
if (
|
|
885
885
|
type(self) is __dataclass__cls
|
|
886
|
-
|
|
886
|
+
or name in __dataclass___delattr_frozen_fields
|
|
887
887
|
):
|
|
888
888
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
889
889
|
super(__dataclass__cls, self).__delattr__(name)
|
|
@@ -1014,7 +1014,7 @@ def _process_dataclass__375fd7fd537e2cfb878109217fe4c57607b10510():
|
|
|
1014
1014
|
def __setattr__(self, name, value):
|
|
1015
1015
|
if (
|
|
1016
1016
|
type(self) is __dataclass__cls
|
|
1017
|
-
|
|
1017
|
+
or name in __dataclass___setattr_frozen_fields
|
|
1018
1018
|
):
|
|
1019
1019
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
1020
1020
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -1031,7 +1031,7 @@ def _process_dataclass__375fd7fd537e2cfb878109217fe4c57607b10510():
|
|
|
1031
1031
|
def __delattr__(self, name):
|
|
1032
1032
|
if (
|
|
1033
1033
|
type(self) is __dataclass__cls
|
|
1034
|
-
|
|
1034
|
+
or name in __dataclass___delattr_frozen_fields
|
|
1035
1035
|
):
|
|
1036
1036
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
1037
1037
|
super(__dataclass__cls, self).__delattr__(name)
|
|
@@ -1163,7 +1163,7 @@ def _process_dataclass__b3f39a9348415b6ae3908bd546728de8b2b6d308():
|
|
|
1163
1163
|
def __setattr__(self, name, value):
|
|
1164
1164
|
if (
|
|
1165
1165
|
type(self) is __dataclass__cls
|
|
1166
|
-
|
|
1166
|
+
or name in __dataclass___setattr_frozen_fields
|
|
1167
1167
|
):
|
|
1168
1168
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
1169
1169
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -1182,7 +1182,7 @@ def _process_dataclass__b3f39a9348415b6ae3908bd546728de8b2b6d308():
|
|
|
1182
1182
|
def __delattr__(self, name):
|
|
1183
1183
|
if (
|
|
1184
1184
|
type(self) is __dataclass__cls
|
|
1185
|
-
|
|
1185
|
+
or name in __dataclass___delattr_frozen_fields
|
|
1186
1186
|
):
|
|
1187
1187
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
1188
1188
|
super(__dataclass__cls, self).__delattr__(name)
|
|
@@ -1317,7 +1317,7 @@ def _process_dataclass__56c73a66344b180e8ef52aca8500185dd538bf10():
|
|
|
1317
1317
|
def __setattr__(self, name, value):
|
|
1318
1318
|
if (
|
|
1319
1319
|
type(self) is __dataclass__cls
|
|
1320
|
-
|
|
1320
|
+
or name in __dataclass___setattr_frozen_fields
|
|
1321
1321
|
):
|
|
1322
1322
|
raise __dataclass__FrozenInstanceError(f"cannot assign to field {name!r}")
|
|
1323
1323
|
super(__dataclass__cls, self).__setattr__(name, value)
|
|
@@ -1335,7 +1335,7 @@ def _process_dataclass__56c73a66344b180e8ef52aca8500185dd538bf10():
|
|
|
1335
1335
|
def __delattr__(self, name):
|
|
1336
1336
|
if (
|
|
1337
1337
|
type(self) is __dataclass__cls
|
|
1338
|
-
|
|
1338
|
+
or name in __dataclass___delattr_frozen_fields
|
|
1339
1339
|
):
|
|
1340
1340
|
raise __dataclass__FrozenInstanceError(f"cannot delete field {name!r}")
|
|
1341
1341
|
super(__dataclass__cls, self).__delattr__(name)
|
omlish/lifecycles/injection.py
CHANGED
|
@@ -123,21 +123,21 @@ def bind_async_lifecycle_registrar() -> inj.Elements:
|
|
|
123
123
|
##
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
def bind_managed_lifecycle_manager() -> inj.Elements:
|
|
126
|
+
def bind_managed_lifecycle_manager(*, eager: bool | int = False) -> inj.Elements:
|
|
127
127
|
# FIXME: lock?
|
|
128
128
|
def inner(es: contextlib.ExitStack) -> LifecycleManager:
|
|
129
129
|
return es.enter_context(lifecycle_context_manage(LifecycleManager()))
|
|
130
130
|
|
|
131
131
|
return inj.as_elements(
|
|
132
|
-
inj.bind(inner, singleton=True, eager=
|
|
132
|
+
inj.bind(inner, singleton=True, eager=eager),
|
|
133
133
|
)
|
|
134
134
|
|
|
135
135
|
|
|
136
|
-
def bind_async_managed_lifecycle_manager() -> inj.Elements:
|
|
136
|
+
def bind_async_managed_lifecycle_manager(*, eager: bool | int = False) -> inj.Elements:
|
|
137
137
|
# FIXME: lock?
|
|
138
138
|
async def inner(aes: contextlib.AsyncExitStack) -> AsyncLifecycleManager:
|
|
139
139
|
return await aes.enter_async_context(async_lifecycle_context_manage(AsyncLifecycleManager()))
|
|
140
140
|
|
|
141
141
|
return inj.as_elements(
|
|
142
|
-
inj.bind(inner, singleton=True, eager=
|
|
142
|
+
inj.bind(inner, singleton=True, eager=eager),
|
|
143
143
|
)
|
omlish/lite/maybes.py
CHANGED
|
@@ -100,6 +100,13 @@ class Maybe(ta.Generic[T]):
|
|
|
100
100
|
else:
|
|
101
101
|
return other
|
|
102
102
|
|
|
103
|
+
@ta.final
|
|
104
|
+
def or_none(self) -> ta.Optional[T]:
|
|
105
|
+
if self.present:
|
|
106
|
+
return self.must()
|
|
107
|
+
else:
|
|
108
|
+
return None
|
|
109
|
+
|
|
103
110
|
@ta.final
|
|
104
111
|
def or_else_get(self, supplier: ta.Callable[[], ta.Union[T, U]]) -> ta.Union[T, U]:
|
|
105
112
|
if self.present:
|