omlish 0.0.0.dev20__py3-none-any.whl → 0.0.0.dev22__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omlish/__about__.py +9 -7
- omlish/asyncs/bridge.py +32 -19
- omlish/bootstrap/diag.py +3 -1
- omlish/concurrent/__init__.py +11 -0
- omlish/concurrent/executors.py +52 -0
- omlish/{concurrent.py → concurrent/futures.py} +0 -44
- omlish/concurrent/threadlets.py +91 -0
- omlish/dataclasses/impl/fields.py +51 -0
- omlish/dataclasses/impl/frozen.py +38 -0
- omlish/dataclasses/impl/main.py +24 -88
- omlish/dataclasses/impl/processing.py +10 -2
- omlish/lang/classes/simple.py +3 -0
- omlish/lang/clsdct.py +2 -0
- omlish/lang/contextmanagers.py +41 -0
- omlish/lang/descriptors.py +6 -0
- omlish/lang/functions.py +3 -0
- omlish/lang/objects.py +4 -0
- omlish/lang/resolving.py +9 -0
- omlish/lite/marshal.py +4 -2
- omlish/logs/__init__.py +4 -0
- omlish/logs/handlers.py +10 -0
- omlish/multiprocessing.py +4 -4
- omlish/secrets/openssl.py +2 -2
- omlish/specs/jsonschema/types.py +11 -0
- {omlish-0.0.0.dev20.dist-info → omlish-0.0.0.dev22.dist-info}/METADATA +13 -9
- {omlish-0.0.0.dev20.dist-info → omlish-0.0.0.dev22.dist-info}/RECORD +29 -25
- {omlish-0.0.0.dev20.dist-info → omlish-0.0.0.dev22.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev20.dist-info → omlish-0.0.0.dev22.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev20.dist-info → omlish-0.0.0.dev22.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
__version__ = '0.0.0.
|
2
|
-
__revision__ = '
|
1
|
+
__version__ = '0.0.0.dev22'
|
2
|
+
__revision__ = '3d902899000237758f62e46319a8da3bccd2d447'
|
3
3
|
|
4
4
|
|
5
5
|
#
|
@@ -33,10 +33,10 @@ class Project(ProjectBase):
|
|
33
33
|
'anyio ~= 4.4',
|
34
34
|
'sniffio ~= 1.3',
|
35
35
|
|
36
|
-
'greenlet ~= 3.
|
36
|
+
'greenlet ~= 3.1',
|
37
37
|
|
38
38
|
'trio ~= 0.26',
|
39
|
-
'trio-asyncio ~= 0.15
|
39
|
+
'trio-asyncio ~= 0.15',
|
40
40
|
],
|
41
41
|
|
42
42
|
'compression': [
|
@@ -46,12 +46,15 @@ class Project(ProjectBase):
|
|
46
46
|
],
|
47
47
|
|
48
48
|
'diag': [
|
49
|
+
'asttokens ~= 2.4',
|
50
|
+
'executing ~= 2.1',
|
51
|
+
|
49
52
|
'psutil ~= 6.0',
|
50
53
|
],
|
51
54
|
|
52
55
|
'formats': [
|
53
56
|
'orjson ~= 3.10',
|
54
|
-
|
57
|
+
'ujson ~= 5.10',
|
55
58
|
|
56
59
|
'json5 ~= 0.9',
|
57
60
|
|
@@ -74,8 +77,7 @@ class Project(ProjectBase):
|
|
74
77
|
],
|
75
78
|
|
76
79
|
'sql': [
|
77
|
-
'sqlalchemy ~= 2.0
|
78
|
-
'sqlalchemy[asyncio] ~= 2.0; python_version < "3.13"',
|
80
|
+
'sqlalchemy[asyncio] ~= 2.0',
|
79
81
|
|
80
82
|
'pg8000 ~= 1.31',
|
81
83
|
'pymysql ~= 1.1',
|
omlish/asyncs/bridge.py
CHANGED
@@ -15,22 +15,21 @@ import types
|
|
15
15
|
import typing as ta
|
16
16
|
import weakref
|
17
17
|
|
18
|
+
from .. import check
|
18
19
|
from .. import lang
|
20
|
+
from .. import sync
|
21
|
+
from ..concurrent import threadlets
|
19
22
|
from .asyncs import sync_await
|
20
23
|
|
21
24
|
|
22
25
|
if ta.TYPE_CHECKING:
|
23
26
|
import asyncio
|
24
27
|
|
25
|
-
import greenlet
|
26
|
-
|
27
28
|
from . import anyio as aiu
|
28
29
|
|
29
30
|
else:
|
30
31
|
asyncio = lang.proxy_import('asyncio')
|
31
32
|
|
32
|
-
greenlet = lang.proxy_import('greenlet')
|
33
|
-
|
34
33
|
aiu = lang.proxy_import('.anyio', __package__)
|
35
34
|
|
36
35
|
|
@@ -56,6 +55,20 @@ def trivial_a_to_s(fn):
|
|
56
55
|
# https://gist.github.com/snaury/202bf4f22c41ca34e56297bae5f33fef
|
57
56
|
|
58
57
|
|
58
|
+
_THREADLETS_IMPL = threadlets.GreenletThreadlets
|
59
|
+
# from ..concurrent.tests.real import RealThreadlets
|
60
|
+
# _THREADLETS_IMPL = RealThreadlets
|
61
|
+
|
62
|
+
_THREADLETS = sync.LazyFn(lambda: _THREADLETS_IMPL())
|
63
|
+
|
64
|
+
|
65
|
+
def _threadlets() -> threadlets.Threadlets:
|
66
|
+
return _THREADLETS.get()
|
67
|
+
|
68
|
+
|
69
|
+
#
|
70
|
+
|
71
|
+
|
59
72
|
class BridgeAwaitRequiredError(Exception):
|
60
73
|
pass
|
61
74
|
|
@@ -101,7 +114,7 @@ def _make_transition(seq: int, a_to_s: bool, obj: ta.Any) -> _BridgeTransition:
|
|
101
114
|
|
102
115
|
_BRIDGED_TASKS: ta.MutableMapping[ta.Any, list[_BridgeTransition]] = weakref.WeakKeyDictionary()
|
103
116
|
|
104
|
-
|
117
|
+
_BRIDGE_THREADLET_ATTR = f'__{__package__.replace(".", "__")}__bridge_threadlet__'
|
105
118
|
|
106
119
|
|
107
120
|
def _push_transition(a_to_s: bool, l: list[_BridgeTransition], t: _BridgeTransition) -> _BridgeTransition:
|
@@ -129,9 +142,9 @@ def _get_transitions() -> list[_BridgeTransition]:
|
|
129
142
|
else:
|
130
143
|
l.extend(tl)
|
131
144
|
|
132
|
-
g =
|
145
|
+
g = _threadlets().get_current()
|
133
146
|
try:
|
134
|
-
gl = getattr(g,
|
147
|
+
gl = getattr(g.underlying, _BRIDGE_THREADLET_ATTR)
|
135
148
|
except AttributeError:
|
136
149
|
pass
|
137
150
|
else:
|
@@ -158,9 +171,9 @@ def is_in_bridge() -> bool:
|
|
158
171
|
else:
|
159
172
|
last_t = None
|
160
173
|
|
161
|
-
g =
|
174
|
+
g = _threadlets().get_current()
|
162
175
|
try:
|
163
|
-
gl = getattr(g,
|
176
|
+
gl = getattr(g.underlying, _BRIDGE_THREADLET_ATTR)
|
164
177
|
except AttributeError:
|
165
178
|
last_g = None
|
166
179
|
else:
|
@@ -194,13 +207,13 @@ def _safe_cancel_awaitable(awaitable: ta.Awaitable[ta.Any]) -> None:
|
|
194
207
|
|
195
208
|
|
196
209
|
def s_to_a_await(awaitable: ta.Awaitable[T]) -> T:
|
197
|
-
g =
|
210
|
+
g = _threadlets().get_current()
|
198
211
|
|
199
|
-
if not getattr(g,
|
212
|
+
if not getattr(g.underlying, _BRIDGE_THREADLET_ATTR, False):
|
200
213
|
_safe_cancel_awaitable(awaitable)
|
201
214
|
raise MissingBridgeGreenletError
|
202
215
|
|
203
|
-
return g.parent.switch(awaitable)
|
216
|
+
return check.not_none(g.parent).switch(awaitable)
|
204
217
|
|
205
218
|
|
206
219
|
def s_to_a(fn, *, require_await=False):
|
@@ -210,7 +223,7 @@ def s_to_a(fn, *, require_await=False):
|
|
210
223
|
try:
|
211
224
|
return fn(*args, **kwargs)
|
212
225
|
finally:
|
213
|
-
if (gl2 := getattr(g,
|
226
|
+
if (gl2 := getattr(g.underlying, _BRIDGE_THREADLET_ATTR)) is not gl: # noqa
|
214
227
|
raise UnexpectedBridgeNestingError
|
215
228
|
if (cur_g := _pop_transition(False, gl)) is not added_g: # noqa
|
216
229
|
raise UnexpectedBridgeNestingError
|
@@ -219,8 +232,8 @@ def s_to_a(fn, *, require_await=False):
|
|
219
232
|
|
220
233
|
seq = next(_BRIDGE_TRANSITIONS_SEQ)
|
221
234
|
|
222
|
-
g =
|
223
|
-
setattr(g,
|
235
|
+
g = _threadlets().spawn(inner)
|
236
|
+
setattr(g.underlying, _BRIDGE_THREADLET_ATTR, gl := []) # type: ignore
|
224
237
|
added_g = _push_transition(False, gl, _make_transition(seq, False, g))
|
225
238
|
|
226
239
|
if (t := aiu.get_current_backend_task()) is not None:
|
@@ -270,11 +283,11 @@ def a_to_s(fn):
|
|
270
283
|
else:
|
271
284
|
added_t = None
|
272
285
|
|
273
|
-
g =
|
286
|
+
g = _threadlets().get_current()
|
274
287
|
try:
|
275
|
-
gl = getattr(g,
|
288
|
+
gl = getattr(g.underlying, _BRIDGE_THREADLET_ATTR)
|
276
289
|
except AttributeError:
|
277
|
-
setattr(g,
|
290
|
+
setattr(g.underlying, _BRIDGE_THREADLET_ATTR, gl := [])
|
278
291
|
added_g = _push_transition(True, gl, _make_transition(seq, True, g))
|
279
292
|
|
280
293
|
try:
|
@@ -306,7 +319,7 @@ def a_to_s(fn):
|
|
306
319
|
if (cur_t := _pop_transition(True, tl)) is not added_t: # noqa
|
307
320
|
raise UnexpectedBridgeNestingError
|
308
321
|
|
309
|
-
if (gl2 := getattr(g,
|
322
|
+
if (gl2 := getattr(g.underlying, _BRIDGE_THREADLET_ATTR)) is not gl: # noqa
|
310
323
|
raise UnexpectedBridgeNestingError
|
311
324
|
if (cur_g := _pop_transition(True, gl)) is not added_g: # noqa
|
312
325
|
raise UnexpectedBridgeNestingError
|
omlish/bootstrap/diag.py
CHANGED
@@ -70,6 +70,7 @@ class ThreadDumpBootstrap(ContextBootstrap['ThreadDumpBootstrap.Config']):
|
|
70
70
|
@dc.dataclass(frozen=True)
|
71
71
|
class Config(Bootstrap.Config):
|
72
72
|
interval_s: ta.Optional[float] = None
|
73
|
+
nodaemon: bool = False
|
73
74
|
|
74
75
|
on_sigquit: bool = False
|
75
76
|
|
@@ -79,6 +80,7 @@ class ThreadDumpBootstrap(ContextBootstrap['ThreadDumpBootstrap.Config']):
|
|
79
80
|
tdt = diagt.create_thread_dump_thread(
|
80
81
|
interval_s=self._config.interval_s,
|
81
82
|
start=True,
|
83
|
+
nodaemon=self._config.nodaemon,
|
82
84
|
)
|
83
85
|
else:
|
84
86
|
tdt = None
|
@@ -97,7 +99,7 @@ class ThreadDumpBootstrap(ContextBootstrap['ThreadDumpBootstrap.Config']):
|
|
97
99
|
yield
|
98
100
|
|
99
101
|
finally:
|
100
|
-
if tdt is not None:
|
102
|
+
if tdt is not None and not self._config.nodaemon:
|
101
103
|
tdt.stop_nowait()
|
102
104
|
|
103
105
|
if prev_sq.present:
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import concurrent.futures as cf
|
2
|
+
import contextlib
|
3
|
+
import typing as ta
|
4
|
+
|
5
|
+
|
6
|
+
T = ta.TypeVar('T')
|
7
|
+
P = ta.ParamSpec('P')
|
8
|
+
|
9
|
+
|
10
|
+
class ImmediateExecutor(cf.Executor):
|
11
|
+
|
12
|
+
def __init__(self, *, immediate_exceptions: bool = False) -> None:
|
13
|
+
super().__init__()
|
14
|
+
self._immediate_exceptions = immediate_exceptions
|
15
|
+
|
16
|
+
def submit(
|
17
|
+
self,
|
18
|
+
fn: ta.Callable[P, T],
|
19
|
+
/,
|
20
|
+
*args: P.args,
|
21
|
+
**kwargs: P.kwargs,
|
22
|
+
) -> cf.Future[T]:
|
23
|
+
future: ta.Any = cf.Future()
|
24
|
+
try:
|
25
|
+
result = fn(*args, **kwargs)
|
26
|
+
future.set_result(result)
|
27
|
+
except Exception as e:
|
28
|
+
if self._immediate_exceptions:
|
29
|
+
raise
|
30
|
+
future.set_exception(e)
|
31
|
+
return future
|
32
|
+
|
33
|
+
|
34
|
+
@contextlib.contextmanager
|
35
|
+
def new_executor(
|
36
|
+
max_workers: int | None = None,
|
37
|
+
cls: type[cf.Executor] = cf.ThreadPoolExecutor,
|
38
|
+
*,
|
39
|
+
immediate_exceptions: bool = False,
|
40
|
+
**kwargs: ta.Any,
|
41
|
+
) -> ta.Generator[cf.Executor, None, None]:
|
42
|
+
if max_workers == 0:
|
43
|
+
yield ImmediateExecutor(
|
44
|
+
immediate_exceptions=immediate_exceptions,
|
45
|
+
)
|
46
|
+
|
47
|
+
else:
|
48
|
+
with cls( # type: ignore
|
49
|
+
max_workers,
|
50
|
+
**kwargs,
|
51
|
+
) as exe:
|
52
|
+
yield exe
|
@@ -1,11 +1,9 @@
|
|
1
1
|
import concurrent.futures as cf
|
2
|
-
import contextlib
|
3
2
|
import time
|
4
3
|
import typing as ta
|
5
4
|
|
6
5
|
|
7
6
|
T = ta.TypeVar('T')
|
8
|
-
P = ta.ParamSpec('P')
|
9
7
|
|
10
8
|
|
11
9
|
##
|
@@ -137,45 +135,3 @@ def wait_dependent_futures(
|
|
137
135
|
|
138
136
|
futs_by_fn = {fn: fut for fut, fn in fns_by_fut.items()}
|
139
137
|
return futs_by_fn
|
140
|
-
|
141
|
-
|
142
|
-
##
|
143
|
-
|
144
|
-
|
145
|
-
class ImmediateExecutor(cf.Executor):
|
146
|
-
|
147
|
-
def __init__(self, *, immediate_exceptions: bool = False) -> None:
|
148
|
-
super().__init__()
|
149
|
-
self._immediate_exceptions = immediate_exceptions
|
150
|
-
|
151
|
-
def submit(self, fn: ta.Callable[P, T], /, *args: P.args, **kwargs: P.kwargs) -> cf.Future[T]:
|
152
|
-
future: ta.Any = cf.Future()
|
153
|
-
try:
|
154
|
-
result = fn(*args, **kwargs)
|
155
|
-
future.set_result(result)
|
156
|
-
except Exception as e:
|
157
|
-
if self._immediate_exceptions:
|
158
|
-
raise
|
159
|
-
future.set_exception(e)
|
160
|
-
return future
|
161
|
-
|
162
|
-
|
163
|
-
@contextlib.contextmanager
|
164
|
-
def new_executor(
|
165
|
-
max_workers: int | None = None,
|
166
|
-
cls: type[cf.Executor] = cf.ThreadPoolExecutor,
|
167
|
-
*,
|
168
|
-
immediate_exceptions: bool = False,
|
169
|
-
**kwargs: ta.Any,
|
170
|
-
) -> ta.Generator[cf.Executor, None, None]:
|
171
|
-
if max_workers == 0:
|
172
|
-
yield ImmediateExecutor(
|
173
|
-
immediate_exceptions=immediate_exceptions,
|
174
|
-
)
|
175
|
-
|
176
|
-
else:
|
177
|
-
with cls( # type: ignore
|
178
|
-
max_workers,
|
179
|
-
**kwargs,
|
180
|
-
) as exe:
|
181
|
-
yield exe
|
@@ -0,0 +1,91 @@
|
|
1
|
+
import abc
|
2
|
+
import dataclasses as dc
|
3
|
+
import typing as ta
|
4
|
+
|
5
|
+
from omlish import lang
|
6
|
+
|
7
|
+
|
8
|
+
if ta.TYPE_CHECKING:
|
9
|
+
import greenlet
|
10
|
+
else:
|
11
|
+
greenlet = lang.proxy_import('greenlet')
|
12
|
+
|
13
|
+
|
14
|
+
##
|
15
|
+
|
16
|
+
|
17
|
+
class Threadlet(abc.ABC):
|
18
|
+
"""Not safe to identity-key - use `underlying`."""
|
19
|
+
|
20
|
+
def __hash__(self):
|
21
|
+
raise TypeError('use `underlying`')
|
22
|
+
|
23
|
+
def __eq__(self, other):
|
24
|
+
raise TypeError('use `underlying`')
|
25
|
+
|
26
|
+
@property
|
27
|
+
@abc.abstractmethod
|
28
|
+
def underlying(self) -> ta.Any:
|
29
|
+
raise NotImplementedError
|
30
|
+
|
31
|
+
@property
|
32
|
+
@abc.abstractmethod
|
33
|
+
def parent(self) -> ta.Optional['Threadlet']:
|
34
|
+
raise NotImplementedError
|
35
|
+
|
36
|
+
@property
|
37
|
+
@abc.abstractmethod
|
38
|
+
def dead(self) -> bool:
|
39
|
+
raise NotImplementedError
|
40
|
+
|
41
|
+
@abc.abstractmethod
|
42
|
+
def switch(self, *args: ta.Any, **kwargs: ta.Any) -> ta.Any:
|
43
|
+
raise NotImplementedError
|
44
|
+
|
45
|
+
@abc.abstractmethod
|
46
|
+
def throw(self, ex: Exception) -> ta.Any:
|
47
|
+
raise NotImplementedError
|
48
|
+
|
49
|
+
|
50
|
+
class Threadlets(abc.ABC):
|
51
|
+
@abc.abstractmethod
|
52
|
+
def spawn(self, fn: ta.Callable[[], None]) -> Threadlet:
|
53
|
+
raise NotImplementedError
|
54
|
+
|
55
|
+
@abc.abstractmethod
|
56
|
+
def get_current(self) -> Threadlet:
|
57
|
+
raise NotImplementedError
|
58
|
+
|
59
|
+
|
60
|
+
##
|
61
|
+
|
62
|
+
|
63
|
+
@dc.dataclass(frozen=True)
|
64
|
+
class GreenletThreadlet(Threadlet):
|
65
|
+
g: 'greenlet.greenlet'
|
66
|
+
|
67
|
+
@property
|
68
|
+
def underlying(self) -> 'greenlet.greenlet':
|
69
|
+
return self.g
|
70
|
+
|
71
|
+
@property
|
72
|
+
def parent(self) -> ta.Optional['GreenletThreadlet']:
|
73
|
+
return GreenletThreadlet(self.g.parent)
|
74
|
+
|
75
|
+
@property
|
76
|
+
def dead(self) -> bool:
|
77
|
+
return self.g.dead
|
78
|
+
|
79
|
+
def switch(self, *args: ta.Any, **kwargs: ta.Any) -> ta.Any:
|
80
|
+
return self.g.switch(*args, **kwargs)
|
81
|
+
|
82
|
+
def throw(self, ex: Exception) -> ta.Any:
|
83
|
+
return self.g.throw(ex)
|
84
|
+
|
85
|
+
|
86
|
+
class GreenletThreadlets(Threadlets):
|
87
|
+
def spawn(self, fn: ta.Callable[[], None]) -> Threadlet:
|
88
|
+
return GreenletThreadlet(greenlet.greenlet(fn))
|
89
|
+
|
90
|
+
def get_current(self) -> Threadlet:
|
91
|
+
return GreenletThreadlet(greenlet.getcurrent())
|
@@ -4,10 +4,13 @@ import typing as ta
|
|
4
4
|
|
5
5
|
from ... import check as check_
|
6
6
|
from ... import lang
|
7
|
+
from .internals import FIELDS_ATTR
|
7
8
|
from .internals import FieldType
|
8
9
|
from .internals import is_classvar
|
9
10
|
from .internals import is_initvar
|
11
|
+
from .internals import is_kw_only
|
10
12
|
from .params import get_field_extras
|
13
|
+
from .processing import Processor
|
11
14
|
|
12
15
|
|
13
16
|
if ta.TYPE_CHECKING:
|
@@ -19,6 +22,9 @@ else:
|
|
19
22
|
MISSING = dc.MISSING
|
20
23
|
|
21
24
|
|
25
|
+
##
|
26
|
+
|
27
|
+
|
22
28
|
def field_type(f: dc.Field) -> FieldType:
|
23
29
|
if (ft := getattr(f, '_field_type')) is not None:
|
24
30
|
return FieldType(ft)
|
@@ -30,6 +36,51 @@ def has_default(f: dc.Field) -> bool:
|
|
30
36
|
return not (f.default is MISSING and f.default_factory is MISSING)
|
31
37
|
|
32
38
|
|
39
|
+
##
|
40
|
+
|
41
|
+
|
42
|
+
class FieldsProcessor(Processor):
|
43
|
+
def _process(self) -> None:
|
44
|
+
cls = self._info.cls
|
45
|
+
fields: dict[str, dc.Field] = {}
|
46
|
+
|
47
|
+
for b in cls.__mro__[-1:0:-1]:
|
48
|
+
base_fields = getattr(b, FIELDS_ATTR, None)
|
49
|
+
if base_fields is not None:
|
50
|
+
for f in base_fields.values():
|
51
|
+
fields[f.name] = f
|
52
|
+
|
53
|
+
cls_fields: list[dc.Field] = []
|
54
|
+
|
55
|
+
kw_only = self._info.params.kw_only
|
56
|
+
kw_only_seen = False
|
57
|
+
for name, ann in self._info.cls_annotations.items():
|
58
|
+
if is_kw_only(cls, ann):
|
59
|
+
if kw_only_seen:
|
60
|
+
raise TypeError(f'{name!r} is KW_ONLY, but KW_ONLY has already been specified')
|
61
|
+
kw_only_seen = True
|
62
|
+
kw_only = True
|
63
|
+
else:
|
64
|
+
cls_fields.append(preprocess_field(cls, name, ann, kw_only))
|
65
|
+
|
66
|
+
for f in cls_fields:
|
67
|
+
fields[f.name] = f
|
68
|
+
if isinstance(getattr(cls, f.name, None), dc.Field):
|
69
|
+
if f.default is MISSING:
|
70
|
+
delattr(cls, f.name)
|
71
|
+
else:
|
72
|
+
setattr(cls, f.name, f.default)
|
73
|
+
|
74
|
+
for name, value in cls.__dict__.items():
|
75
|
+
if isinstance(value, dc.Field) and name not in self._info.cls_annotations:
|
76
|
+
raise TypeError(f'{name!r} is a field but has no type annotation')
|
77
|
+
|
78
|
+
setattr(cls, FIELDS_ATTR, fields)
|
79
|
+
|
80
|
+
|
81
|
+
##
|
82
|
+
|
83
|
+
|
33
84
|
def preprocess_field(
|
34
85
|
cls: type,
|
35
86
|
a_name: str,
|
@@ -1,12 +1,47 @@
|
|
1
1
|
import dataclasses as dc
|
2
2
|
import typing as ta
|
3
3
|
|
4
|
+
from ... import lang
|
5
|
+
from .internals import FIELDS_ATTR
|
6
|
+
from .internals import PARAMS_ATTR
|
4
7
|
from .processing import Processor
|
8
|
+
from .reflect import ClassInfo
|
5
9
|
from .utils import Namespace
|
6
10
|
from .utils import create_fn
|
7
11
|
from .utils import set_new_attribute
|
8
12
|
|
9
13
|
|
14
|
+
if ta.TYPE_CHECKING:
|
15
|
+
from . import metaclass
|
16
|
+
else:
|
17
|
+
metaclass = lang.proxy_import('.metaclass', __package__)
|
18
|
+
|
19
|
+
|
20
|
+
def check_frozen_bases(info: ClassInfo) -> None:
|
21
|
+
mc_base = getattr(metaclass, 'Data', None)
|
22
|
+
all_frozen_bases = None
|
23
|
+
any_frozen_base = False
|
24
|
+
has_dataclass_bases = False
|
25
|
+
for b in info.cls.__mro__[-1:0:-1]:
|
26
|
+
if b is mc_base:
|
27
|
+
continue
|
28
|
+
base_fields = getattr(b, FIELDS_ATTR, None)
|
29
|
+
if base_fields is not None:
|
30
|
+
has_dataclass_bases = True
|
31
|
+
if all_frozen_bases is None:
|
32
|
+
all_frozen_bases = True
|
33
|
+
current_frozen = getattr(b, PARAMS_ATTR).frozen
|
34
|
+
all_frozen_bases = all_frozen_bases and current_frozen
|
35
|
+
any_frozen_base = any_frozen_base or current_frozen
|
36
|
+
|
37
|
+
if has_dataclass_bases:
|
38
|
+
if any_frozen_base and not info.params.frozen:
|
39
|
+
raise TypeError('cannot inherit non-frozen dataclass from a frozen one')
|
40
|
+
|
41
|
+
if all_frozen_bases is False and info.params.frozen:
|
42
|
+
raise TypeError('cannot inherit frozen dataclass from a non-frozen one')
|
43
|
+
|
44
|
+
|
10
45
|
def frozen_get_del_attr(
|
11
46
|
cls: type,
|
12
47
|
fields: ta.Sequence[dc.Field],
|
@@ -46,6 +81,9 @@ def frozen_get_del_attr(
|
|
46
81
|
|
47
82
|
|
48
83
|
class FrozenProcessor(Processor):
|
84
|
+
def check(self) -> None:
|
85
|
+
check_frozen_bases(self._info)
|
86
|
+
|
49
87
|
def _process(self) -> None:
|
50
88
|
if not self._info.params.frozen:
|
51
89
|
return
|
omlish/dataclasses/impl/main.py
CHANGED
@@ -5,14 +5,13 @@ import typing as ta
|
|
5
5
|
from ... import check
|
6
6
|
from ... import lang
|
7
7
|
from .copy import CopyProcessor
|
8
|
-
from .fields import
|
8
|
+
from .fields import FieldsProcessor
|
9
9
|
from .frozen import FrozenProcessor
|
10
10
|
from .hashing import HashProcessor
|
11
11
|
from .init import InitProcessor
|
12
12
|
from .internals import FIELDS_ATTR
|
13
13
|
from .internals import PARAMS_ATTR
|
14
14
|
from .internals import Params
|
15
|
-
from .internals import is_kw_only
|
16
15
|
from .order import OrderProcessor
|
17
16
|
from .params import ParamsExtras
|
18
17
|
from .processing import Processor
|
@@ -26,12 +25,6 @@ from .simple import OverridesProcessor
|
|
26
25
|
from .slots import add_slots
|
27
26
|
|
28
27
|
|
29
|
-
if ta.TYPE_CHECKING:
|
30
|
-
from . import metaclass
|
31
|
-
else:
|
32
|
-
metaclass = lang.proxy_import('.metaclass', __package__)
|
33
|
-
|
34
|
-
|
35
28
|
MISSING = dc.MISSING
|
36
29
|
|
37
30
|
|
@@ -50,67 +43,6 @@ class MainProcessor:
|
|
50
43
|
if self._info.params.order and not self._info.params.eq:
|
51
44
|
raise ValueError('eq must be true if order is true')
|
52
45
|
|
53
|
-
def _check_frozen_bases(self) -> None:
|
54
|
-
mc_base = getattr(metaclass, 'Data', None)
|
55
|
-
all_frozen_bases = None
|
56
|
-
any_frozen_base = False
|
57
|
-
has_dataclass_bases = False
|
58
|
-
for b in self._cls.__mro__[-1:0:-1]:
|
59
|
-
if b is mc_base:
|
60
|
-
continue
|
61
|
-
base_fields = getattr(b, FIELDS_ATTR, None)
|
62
|
-
if base_fields is not None:
|
63
|
-
has_dataclass_bases = True
|
64
|
-
if all_frozen_bases is None:
|
65
|
-
all_frozen_bases = True
|
66
|
-
current_frozen = getattr(b, PARAMS_ATTR).frozen
|
67
|
-
all_frozen_bases = all_frozen_bases and current_frozen
|
68
|
-
any_frozen_base = any_frozen_base or current_frozen
|
69
|
-
|
70
|
-
if has_dataclass_bases:
|
71
|
-
if any_frozen_base and not self._info.params.frozen:
|
72
|
-
raise TypeError('cannot inherit non-frozen dataclass from a frozen one')
|
73
|
-
|
74
|
-
if all_frozen_bases is False and self._info.params.frozen:
|
75
|
-
raise TypeError('cannot inherit frozen dataclass from a non-frozen one')
|
76
|
-
|
77
|
-
@lang.cached_function
|
78
|
-
def _process_fields(self) -> None:
|
79
|
-
fields: dict[str, dc.Field] = {}
|
80
|
-
|
81
|
-
for b in self._cls.__mro__[-1:0:-1]:
|
82
|
-
base_fields = getattr(b, FIELDS_ATTR, None)
|
83
|
-
if base_fields is not None:
|
84
|
-
for f in base_fields.values():
|
85
|
-
fields[f.name] = f
|
86
|
-
|
87
|
-
cls_fields: list[dc.Field] = []
|
88
|
-
|
89
|
-
kw_only = self._info.params.kw_only
|
90
|
-
kw_only_seen = False
|
91
|
-
for name, ann in self._info.cls_annotations.items():
|
92
|
-
if is_kw_only(self._cls, ann):
|
93
|
-
if kw_only_seen:
|
94
|
-
raise TypeError(f'{name!r} is KW_ONLY, but KW_ONLY has already been specified')
|
95
|
-
kw_only_seen = True
|
96
|
-
kw_only = True
|
97
|
-
else:
|
98
|
-
cls_fields.append(preprocess_field(self._cls, name, ann, kw_only))
|
99
|
-
|
100
|
-
for f in cls_fields:
|
101
|
-
fields[f.name] = f
|
102
|
-
if isinstance(getattr(self._cls, f.name, None), dc.Field):
|
103
|
-
if f.default is MISSING:
|
104
|
-
delattr(self._cls, f.name)
|
105
|
-
else:
|
106
|
-
setattr(self._cls, f.name, f.default)
|
107
|
-
|
108
|
-
for name, value in self._cls.__dict__.items():
|
109
|
-
if isinstance(value, dc.Field) and name not in self._info.cls_annotations:
|
110
|
-
raise TypeError(f'{name!r} is a field but has no type annotation')
|
111
|
-
|
112
|
-
setattr(self._cls, FIELDS_ATTR, fields)
|
113
|
-
|
114
46
|
@lang.cached_function
|
115
47
|
def _transform_slots(self) -> None:
|
116
48
|
if self._info.params.weakref_slot and not self._info.params.slots:
|
@@ -119,28 +51,32 @@ class MainProcessor:
|
|
119
51
|
return
|
120
52
|
self._cls = add_slots(self._cls, self._info.params.frozen, self._info.params.weakref_slot)
|
121
53
|
|
54
|
+
PROCESSOR_TYPES: ta.ClassVar[ta.Sequence[type[Processor]]] = [
|
55
|
+
FieldsProcessor,
|
56
|
+
InitProcessor,
|
57
|
+
OverridesProcessor,
|
58
|
+
ReprProcessor,
|
59
|
+
EqProcessor,
|
60
|
+
OrderProcessor,
|
61
|
+
FrozenProcessor,
|
62
|
+
HashProcessor,
|
63
|
+
DocProcessor,
|
64
|
+
MatchArgsProcessor,
|
65
|
+
ReplaceProcessor,
|
66
|
+
CopyProcessor,
|
67
|
+
]
|
68
|
+
|
122
69
|
@lang.cached_function
|
123
70
|
def process(self) -> type:
|
124
71
|
self._check_params()
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
ReprProcessor,
|
134
|
-
EqProcessor,
|
135
|
-
OrderProcessor,
|
136
|
-
FrozenProcessor,
|
137
|
-
HashProcessor,
|
138
|
-
DocProcessor,
|
139
|
-
MatchArgsProcessor,
|
140
|
-
ReplaceProcessor,
|
141
|
-
CopyProcessor,
|
142
|
-
]:
|
143
|
-
pcls(self._info).process()
|
72
|
+
|
73
|
+
ps = [pcls(self._info) for pcls in self.PROCESSOR_TYPES]
|
74
|
+
|
75
|
+
for p in ps:
|
76
|
+
p.check()
|
77
|
+
|
78
|
+
for p in ps:
|
79
|
+
p.process()
|
144
80
|
|
145
81
|
self._transform_slots()
|
146
82
|
|
@@ -1,13 +1,21 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
1
3
|
from ... import lang
|
2
|
-
|
4
|
+
|
5
|
+
|
6
|
+
if ta.TYPE_CHECKING:
|
7
|
+
from .reflect import ClassInfo
|
3
8
|
|
4
9
|
|
5
10
|
class Processor(lang.Abstract):
|
6
|
-
def __init__(self, info: ClassInfo) -> None:
|
11
|
+
def __init__(self, info: 'ClassInfo') -> None:
|
7
12
|
super().__init__()
|
8
13
|
self._cls = info.cls
|
9
14
|
self._info = info
|
10
15
|
|
16
|
+
def check(self) -> None:
|
17
|
+
pass
|
18
|
+
|
11
19
|
@lang.cached_function
|
12
20
|
def process(self) -> None:
|
13
21
|
self._process()
|
omlish/lang/classes/simple.py
CHANGED
@@ -45,15 +45,18 @@ class _MarkerMeta(abc.ABCMeta):
|
|
45
45
|
|
46
46
|
def __new__(mcls, name, bases, namespace):
|
47
47
|
global _MARKER_NAMESPACE_KEYS
|
48
|
+
|
48
49
|
if _MARKER_NAMESPACE_KEYS is None:
|
49
50
|
if not (namespace.get('__module__') == __name__ and name == 'Marker'):
|
50
51
|
raise RuntimeError
|
51
52
|
_MARKER_NAMESPACE_KEYS = set(namespace)
|
53
|
+
|
52
54
|
else:
|
53
55
|
if set(namespace) - _MARKER_NAMESPACE_KEYS:
|
54
56
|
raise TypeError('Markers must not include contents. Did you mean to use Namespace?')
|
55
57
|
if Final not in bases:
|
56
58
|
bases += (Final,)
|
59
|
+
|
57
60
|
return super().__new__(mcls, name, bases, namespace)
|
58
61
|
|
59
62
|
def __instancecheck__(self, instance):
|
omlish/lang/clsdct.py
CHANGED
omlish/lang/contextmanagers.py
CHANGED
@@ -227,6 +227,47 @@ class ExitStacked:
|
|
227
227
|
return superfn(exc_type, exc_val, exc_tb)
|
228
228
|
|
229
229
|
|
230
|
+
class AsyncExitStacked:
|
231
|
+
|
232
|
+
@property
|
233
|
+
def _exit_stack(self) -> contextlib.AsyncExitStack:
|
234
|
+
try:
|
235
|
+
return self.__exit_stack # type: ignore
|
236
|
+
except AttributeError:
|
237
|
+
es = self.__exit_stack = contextlib.AsyncExitStack()
|
238
|
+
return es
|
239
|
+
|
240
|
+
async def _enter_async_context(self, context_manager: ta.AsyncContextManager[T]) -> T:
|
241
|
+
return await self._exit_stack.enter_async_context(ta.cast(ta.AsyncContextManager, context_manager))
|
242
|
+
|
243
|
+
def _enter_context(self, context_manager: ta.ContextManager[T]) -> T:
|
244
|
+
return self._exit_stack.enter_context(ta.cast(ta.ContextManager, context_manager))
|
245
|
+
|
246
|
+
async def __aenter__(self) -> ta.Self:
|
247
|
+
try:
|
248
|
+
superfn = super().__aenter__ # type: ignore
|
249
|
+
except AttributeError:
|
250
|
+
ret = self
|
251
|
+
else:
|
252
|
+
ret = await superfn()
|
253
|
+
await self._exit_stack.__aenter__()
|
254
|
+
return ret
|
255
|
+
|
256
|
+
async def __aexit__(
|
257
|
+
self,
|
258
|
+
exc_type: type[BaseException] | None,
|
259
|
+
exc_val: BaseException | None,
|
260
|
+
exc_tb: types.TracebackType | None,
|
261
|
+
) -> bool | None:
|
262
|
+
await self._exit_stack.__aexit__(exc_type, exc_val, exc_tb)
|
263
|
+
try:
|
264
|
+
superfn = super().__aexit__ # type: ignore
|
265
|
+
except AttributeError:
|
266
|
+
return None
|
267
|
+
else:
|
268
|
+
return await superfn(exc_type, exc_val, exc_tb)
|
269
|
+
|
270
|
+
|
230
271
|
##
|
231
272
|
|
232
273
|
|
omlish/lang/descriptors.py
CHANGED
@@ -37,8 +37,10 @@ def _has_method_descriptor(obj: ta.Any) -> bool:
|
|
37
37
|
while True:
|
38
38
|
if is_method_descriptor(obj):
|
39
39
|
return True
|
40
|
+
|
40
41
|
elif isinstance(obj, functools.partial):
|
41
42
|
obj = obj.func
|
43
|
+
|
42
44
|
else:
|
43
45
|
try:
|
44
46
|
obj = getattr(obj, '__wrapped__')
|
@@ -65,6 +67,7 @@ def unwrap_func_with_partials(fn: ta.Callable) -> tuple[ta.Callable, list[functo
|
|
65
67
|
while True:
|
66
68
|
if is_method_descriptor(fn) or isinstance(fn, types.MethodType):
|
67
69
|
fn = fn.__func__ # type: ignore
|
70
|
+
|
68
71
|
elif hasattr(fn, '__wrapped__'):
|
69
72
|
nxt = fn.__wrapped__
|
70
73
|
if not callable(nxt):
|
@@ -72,13 +75,16 @@ def unwrap_func_with_partials(fn: ta.Callable) -> tuple[ta.Callable, list[functo
|
|
72
75
|
if nxt is fn:
|
73
76
|
raise TypeError(fn)
|
74
77
|
fn = nxt
|
78
|
+
|
75
79
|
# NOTE: __wrapped__ takes precedence - a partial might point to a bound Method when the important information is
|
76
80
|
# still the unbound func. see _decorator_descriptor for an example of this.
|
77
81
|
elif isinstance(fn, functools.partial):
|
78
82
|
ps.append(fn)
|
79
83
|
fn = fn.func
|
84
|
+
|
80
85
|
else:
|
81
86
|
break
|
87
|
+
|
82
88
|
return fn, ps
|
83
89
|
|
84
90
|
|
omlish/lang/functions.py
CHANGED
omlish/lang/objects.py
CHANGED
@@ -105,20 +105,24 @@ def build_mro_dict(
|
|
105
105
|
) -> ta.Mapping[str, ta.Any]:
|
106
106
|
if owner_cls is None:
|
107
107
|
owner_cls = instance_cls
|
108
|
+
|
108
109
|
mro = instance_cls.__mro__[-2::-1]
|
109
110
|
try:
|
110
111
|
pos = mro.index(owner_cls)
|
111
112
|
except ValueError:
|
112
113
|
raise TypeError(f'Owner class {owner_cls} not in mro of instance class {instance_cls}') from None
|
114
|
+
|
113
115
|
dct: dict[str, ta.Any] = {}
|
114
116
|
if not bottom_up_key_order:
|
115
117
|
for cur_cls in mro[:pos + 1][::-1]:
|
116
118
|
for k, v in cur_cls.__dict__.items():
|
117
119
|
if k not in dct:
|
118
120
|
dct[k] = v
|
121
|
+
|
119
122
|
else:
|
120
123
|
for cur_cls in mro[:pos + 1]:
|
121
124
|
dct.update(cur_cls.__dict__)
|
125
|
+
|
122
126
|
return dct
|
123
127
|
|
124
128
|
|
omlish/lang/resolving.py
CHANGED
@@ -10,37 +10,46 @@ class ResolvableClassNameError(NameError):
|
|
10
10
|
def get_cls_fqcn(cls: type, *, nocheck: bool = False) -> str:
|
11
11
|
if not isinstance(cls, type):
|
12
12
|
raise TypeError(cls)
|
13
|
+
|
13
14
|
mn = cls.__module__
|
14
15
|
if set(mn) - set(string.ascii_lowercase + string.digits + '_.'):
|
15
16
|
raise ResolvableClassNameError(cls)
|
17
|
+
|
16
18
|
qn = cls.__qualname__
|
17
19
|
if not all(qp[0].isupper() for qp in qn.split('.')) or (set(qn) - set(string.ascii_letters + string.digits + '.')):
|
18
20
|
raise ResolvableClassNameError(cls)
|
21
|
+
|
19
22
|
fqcn = '.'.join([cls.__module__, cls.__qualname__])
|
20
23
|
if not nocheck:
|
21
24
|
if get_fqcn_cls(fqcn, nocheck=True) is not cls:
|
22
25
|
raise ResolvableClassNameError(cls, fqcn)
|
26
|
+
|
23
27
|
return fqcn
|
24
28
|
|
25
29
|
|
26
30
|
def get_fqcn_cls(fqcn: str, *, nocheck: bool = False) -> type:
|
27
31
|
if not isinstance(fqcn, str) or not fqcn:
|
28
32
|
raise TypeError(fqcn)
|
33
|
+
|
29
34
|
parts = fqcn.split('.')
|
30
35
|
pos = next(i for i, p in enumerate(parts) if p[0].isupper())
|
31
36
|
mps, qps = parts[:pos], parts[pos:]
|
32
37
|
mod = importlib.import_module('.'.join(mps))
|
38
|
+
|
33
39
|
o: ta.Any = mod
|
34
40
|
for qp in qps:
|
35
41
|
o = getattr(o, qp)
|
36
42
|
if not isinstance(o, type):
|
37
43
|
raise TypeError(o)
|
44
|
+
|
38
45
|
cls = o
|
39
46
|
if not isinstance(cls, type):
|
40
47
|
raise TypeError(cls)
|
48
|
+
|
41
49
|
if not nocheck:
|
42
50
|
if not get_cls_fqcn(cls, nocheck=True) == fqcn:
|
43
51
|
raise ResolvableClassNameError(cls, fqcn)
|
52
|
+
|
44
53
|
return o
|
45
54
|
|
46
55
|
|
omlish/lite/marshal.py
CHANGED
@@ -232,8 +232,10 @@ _OBJ_MARSHALER_GENERIC_MAPPING_TYPES: ta.Dict[ta.Any, type] = {
|
|
232
232
|
|
233
233
|
_OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
|
234
234
|
**{t: t for t in (list, tuple, set, frozenset)},
|
235
|
-
|
236
|
-
|
235
|
+
collections.abc.Set: frozenset,
|
236
|
+
collections.abc.MutableSet: set,
|
237
|
+
collections.abc.Sequence: tuple,
|
238
|
+
collections.abc.MutableSequence: list,
|
237
239
|
}
|
238
240
|
|
239
241
|
|
omlish/logs/__init__.py
CHANGED
omlish/logs/handlers.py
ADDED
omlish/multiprocessing.py
CHANGED
@@ -47,19 +47,19 @@ class DummyValueProxy(ValueProxy[T]):
|
|
47
47
|
|
48
48
|
@dc.dataclass(frozen=True, kw_only=True)
|
49
49
|
class SpawnExtras:
|
50
|
-
|
50
|
+
pass_fds: ta.AbstractSet[int] | None = None
|
51
51
|
deathsig: int | None = None
|
52
52
|
|
53
53
|
|
54
54
|
class ExtrasSpawnPosixPopen(mp.popen_spawn_posix.Popen):
|
55
55
|
def __init__(self, process_obj: 'ExtrasSpawnProcess', *, extras: SpawnExtras) -> None:
|
56
56
|
self.__extras = extras
|
57
|
-
self.
|
57
|
+
self.__pass_fds = extras.pass_fds
|
58
58
|
super().__init__(process_obj)
|
59
59
|
|
60
60
|
def _launch(self, process_obj: 'ExtrasSpawnProcess') -> None:
|
61
|
-
if self.
|
62
|
-
for fd in self.
|
61
|
+
if self.__pass_fds:
|
62
|
+
for fd in self.__pass_fds:
|
63
63
|
self.duplicate_for_child(fd)
|
64
64
|
self._extra_fds = None
|
65
65
|
|
omlish/secrets/openssl.py
CHANGED
@@ -42,7 +42,7 @@ def generate_key(self, sz: int = DEFAULT_KEY_SIZE) -> bytes:
|
|
42
42
|
##
|
43
43
|
|
44
44
|
|
45
|
-
class
|
45
|
+
class OpensslAescbcCrypto(Crypto):
|
46
46
|
"""
|
47
47
|
!!! https://docs.openssl.org/3.0/man7/passphrase-encoding/
|
48
48
|
https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#cryptography.hazmat.primitives.ciphers.Cipher
|
@@ -122,7 +122,7 @@ class OpensslAes265CbcCrypto(Crypto):
|
|
122
122
|
##
|
123
123
|
|
124
124
|
|
125
|
-
class
|
125
|
+
class OpensslSubprocessAescbcCrypto(Crypto):
|
126
126
|
def __init__(
|
127
127
|
self,
|
128
128
|
*,
|
omlish/specs/jsonschema/types.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import enum
|
2
|
+
import typing as ta
|
2
3
|
|
3
4
|
|
4
5
|
class JsonType(enum.Enum):
|
@@ -8,3 +9,13 @@ class JsonType(enum.Enum):
|
|
8
9
|
ARRAY = enum.auto()
|
9
10
|
NUMBER = enum.auto()
|
10
11
|
STRING = enum.auto()
|
12
|
+
|
13
|
+
|
14
|
+
TYPE_SETS_BY_JSON_TYPE: ta.Mapping[JsonType, ta.AbstractSet[type]] = {
|
15
|
+
JsonType.NULL: {type(None)},
|
16
|
+
JsonType.BOOLEAN: {bool},
|
17
|
+
JsonType.OBJECT: {dict},
|
18
|
+
JsonType.ARRAY: {list},
|
19
|
+
JsonType.NUMBER: {int, float},
|
20
|
+
JsonType.STRING: {str},
|
21
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: omlish
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev22
|
4
4
|
Summary: omlish
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -15,11 +15,16 @@ License-File: LICENSE
|
|
15
15
|
Provides-Extra: all
|
16
16
|
Requires-Dist: anyio ~=4.4 ; extra == 'all'
|
17
17
|
Requires-Dist: sniffio ~=1.3 ; extra == 'all'
|
18
|
+
Requires-Dist: greenlet ~=3.1 ; extra == 'all'
|
18
19
|
Requires-Dist: trio ~=0.26 ; extra == 'all'
|
20
|
+
Requires-Dist: trio-asyncio ~=0.15 ; extra == 'all'
|
19
21
|
Requires-Dist: lz4 ~=4.0 ; extra == 'all'
|
20
22
|
Requires-Dist: zstd ~=1.5 ; extra == 'all'
|
23
|
+
Requires-Dist: asttokens ~=2.4 ; extra == 'all'
|
24
|
+
Requires-Dist: executing ~=2.1 ; extra == 'all'
|
21
25
|
Requires-Dist: psutil ~=6.0 ; extra == 'all'
|
22
26
|
Requires-Dist: orjson ~=3.10 ; extra == 'all'
|
27
|
+
Requires-Dist: ujson ~=5.10 ; extra == 'all'
|
23
28
|
Requires-Dist: json5 ~=0.9 ; extra == 'all'
|
24
29
|
Requires-Dist: pyyaml ~=5.0 ; extra == 'all'
|
25
30
|
Requires-Dist: cloudpickle ~=3.0 ; extra == 'all'
|
@@ -27,33 +32,33 @@ Requires-Dist: httpx[http2] ~=0.27 ; extra == 'all'
|
|
27
32
|
Requires-Dist: jinja2 ~=3.1 ; extra == 'all'
|
28
33
|
Requires-Dist: wrapt ~=1.14 ; extra == 'all'
|
29
34
|
Requires-Dist: cryptography ~=43.0 ; extra == 'all'
|
35
|
+
Requires-Dist: sqlalchemy[asyncio] ~=2.0 ; extra == 'all'
|
30
36
|
Requires-Dist: pg8000 ~=1.31 ; extra == 'all'
|
31
37
|
Requires-Dist: pymysql ~=1.1 ; extra == 'all'
|
32
38
|
Requires-Dist: aiomysql ~=0.2 ; extra == 'all'
|
33
39
|
Requires-Dist: aiosqlite ~=0.20 ; extra == 'all'
|
34
40
|
Requires-Dist: duckdb ~=1.1 ; extra == 'all'
|
35
41
|
Requires-Dist: pytest ~=8.0 ; extra == 'all'
|
36
|
-
Requires-Dist: greenlet ~=3.0 ; (python_version < "3.13") and extra == 'all'
|
37
|
-
Requires-Dist: trio-asyncio ~=0.15 ; (python_version < "3.13") and extra == 'all'
|
38
42
|
Requires-Dist: python-snappy ~=0.7 ; (python_version < "3.13") and extra == 'all'
|
39
|
-
Requires-Dist: sqlalchemy[asyncio] ~=2.0 ; (python_version < "3.13") and extra == 'all'
|
40
43
|
Requires-Dist: asyncpg ~=0.29 ; (python_version < "3.13") and extra == 'all'
|
41
44
|
Requires-Dist: sqlean.py ~=3.45 ; (python_version < "3.13") and extra == 'all'
|
42
|
-
Requires-Dist: sqlalchemy ~=2.0 ; (python_version ~= "3.13") and extra == 'all'
|
43
45
|
Provides-Extra: async
|
44
46
|
Requires-Dist: anyio ~=4.4 ; extra == 'async'
|
45
47
|
Requires-Dist: sniffio ~=1.3 ; extra == 'async'
|
48
|
+
Requires-Dist: greenlet ~=3.1 ; extra == 'async'
|
46
49
|
Requires-Dist: trio ~=0.26 ; extra == 'async'
|
47
|
-
Requires-Dist:
|
48
|
-
Requires-Dist: trio-asyncio ~=0.15 ; (python_version < "3.13") and extra == 'async'
|
50
|
+
Requires-Dist: trio-asyncio ~=0.15 ; extra == 'async'
|
49
51
|
Provides-Extra: compression
|
50
52
|
Requires-Dist: lz4 ~=4.0 ; extra == 'compression'
|
51
53
|
Requires-Dist: zstd ~=1.5 ; extra == 'compression'
|
52
54
|
Requires-Dist: python-snappy ~=0.7 ; (python_version < "3.13") and extra == 'compression'
|
53
55
|
Provides-Extra: diag
|
56
|
+
Requires-Dist: asttokens ~=2.4 ; extra == 'diag'
|
57
|
+
Requires-Dist: executing ~=2.1 ; extra == 'diag'
|
54
58
|
Requires-Dist: psutil ~=6.0 ; extra == 'diag'
|
55
59
|
Provides-Extra: formats
|
56
60
|
Requires-Dist: orjson ~=3.10 ; extra == 'formats'
|
61
|
+
Requires-Dist: ujson ~=5.10 ; extra == 'formats'
|
57
62
|
Requires-Dist: json5 ~=0.9 ; extra == 'formats'
|
58
63
|
Requires-Dist: pyyaml ~=5.0 ; extra == 'formats'
|
59
64
|
Requires-Dist: cloudpickle ~=3.0 ; extra == 'formats'
|
@@ -65,13 +70,12 @@ Requires-Dist: wrapt ~=1.14 ; extra == 'misc'
|
|
65
70
|
Provides-Extra: secrets
|
66
71
|
Requires-Dist: cryptography ~=43.0 ; extra == 'secrets'
|
67
72
|
Provides-Extra: sql
|
73
|
+
Requires-Dist: sqlalchemy[asyncio] ~=2.0 ; extra == 'sql'
|
68
74
|
Requires-Dist: pg8000 ~=1.31 ; extra == 'sql'
|
69
75
|
Requires-Dist: pymysql ~=1.1 ; extra == 'sql'
|
70
76
|
Requires-Dist: aiomysql ~=0.2 ; extra == 'sql'
|
71
77
|
Requires-Dist: aiosqlite ~=0.20 ; extra == 'sql'
|
72
|
-
Requires-Dist: sqlalchemy[asyncio] ~=2.0 ; (python_version < "3.13") and extra == 'sql'
|
73
78
|
Requires-Dist: asyncpg ~=0.29 ; (python_version < "3.13") and extra == 'sql'
|
74
|
-
Requires-Dist: sqlalchemy ~=2.0 ; (python_version ~= "3.13") and extra == 'sql'
|
75
79
|
Provides-Extra: sqlx
|
76
80
|
Requires-Dist: duckdb ~=1.1 ; extra == 'sqlx'
|
77
81
|
Requires-Dist: sqlean.py ~=3.45 ; (python_version < "3.13") and extra == 'sqlx'
|
@@ -1,10 +1,9 @@
|
|
1
|
-
omlish/__about__.py,sha256=
|
1
|
+
omlish/__about__.py,sha256=V2bnCKc-3aJwdTP1xtp2ipVCaAqOuhGj6P8aqD-yHvs,2380
|
2
2
|
omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
omlish/argparse.py,sha256=QRQmX9G0-L_nATkFtGHvpd4qrpYzKATdjuFLbBqzJPM,6224
|
4
4
|
omlish/c3.py,sha256=W5EwYx9Por3rWYLkKUitJ6OoRMLLgVTfLTyroOz41Y0,8047
|
5
5
|
omlish/cached.py,sha256=UAizxlH4eMWHPzQtmItmyE6FEpFEUFzIkxaO2BHWZ5s,196
|
6
6
|
omlish/check.py,sha256=o3UJnIEmmRsv9ggIIDtz8fDSudW1CatxbwxP42M4dno,5543
|
7
|
-
omlish/concurrent.py,sha256=jCGG76Ca_8761g1uY3nCJONg_Nxcf4JQQZYvvrmsKE4,5395
|
8
7
|
omlish/datetimes.py,sha256=HajeM1kBvwlTa-uR1TTZHmZ3zTPnnUr1uGGQhiO1XQ0,2152
|
9
8
|
omlish/defs.py,sha256=T3bq_7h_tO3nDB5RAFBn7DkdeQgqheXzkFColbOHZko,4890
|
10
9
|
omlish/docker.py,sha256=5WyXJyFwqIJJ11QWwPIjHjDHnsaOVZszZAjyTvg3xew,4693
|
@@ -14,7 +13,7 @@ omlish/iterators.py,sha256=GGLC7RIT86uXMjhIIIqnff_Iu5SI_b9rXYywYGFyzmo,7292
|
|
14
13
|
omlish/libc.py,sha256=u0481imCiTFqP_e-v9g0pD-0WD249j5vYzhtn-fnNkY,15308
|
15
14
|
omlish/matchfns.py,sha256=o2evI7q0CAMHR8RQ_Jks6L0UoNpEDltnLjOiamJDtmU,6155
|
16
15
|
omlish/math.py,sha256=AVqp5Y8yxKA-wO0BgrzaxA0Ga3PZiCXnYcwivMneC-0,3804
|
17
|
-
omlish/multiprocessing.py,sha256=
|
16
|
+
omlish/multiprocessing.py,sha256=QZT4C7I-uThCAjaEY3xgUYb-5GagUlnE4etN01LDyU4,5186
|
18
17
|
omlish/os.py,sha256=cz4nL2ujaxH_-XRq3JUD8af8mSe1JXGPIoXP9XAEd0M,2607
|
19
18
|
omlish/runmodule.py,sha256=PWvuAaJ9wQQn6bx9ftEL3_d04DyotNn8dR_twm2pgw0,700
|
20
19
|
omlish/stats.py,sha256=uqjN-focDVssFZMagj22HqmyJ1TBO4Wt-XnHp8-EtVw,9927
|
@@ -24,14 +23,14 @@ omlish/asyncs/__init__.py,sha256=uUz9ziKh4_QrgmdhKFMgq6j7mFbiZd3LiogguDCQsGI,587
|
|
24
23
|
omlish/asyncs/anyio.py,sha256=Hqdi1iCopKoaAWGx-AYTRLEwnavLWx1esfJISK1IVF0,8024
|
25
24
|
omlish/asyncs/asyncio.py,sha256=JfM59QgB3asgEbrps0zoVbNjWD4kL2XdsEkRMEIoFos,971
|
26
25
|
omlish/asyncs/asyncs.py,sha256=Tf7ZodTGepkM7HAuFcDNh9lLzzrMw6rELWvopGmFkh4,2035
|
27
|
-
omlish/asyncs/bridge.py,sha256=
|
26
|
+
omlish/asyncs/bridge.py,sha256=dTVJrubiPlP0PlgJQT1Pj0jNDXFuPADtWymwSsgbl4k,8575
|
28
27
|
omlish/asyncs/flavors.py,sha256=1mNxGNRVmjUHzA13K5ht8vdJv4CLEmzYTQ6BZXr1520,4866
|
29
28
|
omlish/asyncs/trio.py,sha256=GKG3wgelFr7gIKKHZhcflvMyCvxXHNZe862KB0Xw2uA,370
|
30
29
|
omlish/asyncs/trio_asyncio.py,sha256=oqdOHy0slj9PjVxaDf3gJkq9AAgg7wYZbB469jOftVw,1327
|
31
30
|
omlish/bootstrap/__init__.py,sha256=Nii56mGsr1MsrQPQTX45kS6NsU0APK5t13Wlb1n8jlo,48
|
32
31
|
omlish/bootstrap/__main__.py,sha256=d23loR_cKfTYZwYiqpt_CmKI7dd5WcYFgIYzqMep75E,68
|
33
32
|
omlish/bootstrap/base.py,sha256=nyf2PYCoYzNEX_78Rm8szqpdTdhhSbSJEt3hf7OncvA,1032
|
34
|
-
omlish/bootstrap/diag.py,sha256=
|
33
|
+
omlish/bootstrap/diag.py,sha256=BQf1MkhT-cY2vJGoSauOMZZagTc73tPV-NqmP5-AGWQ,3107
|
35
34
|
omlish/bootstrap/harness.py,sha256=vQCIhCQY_N0NHWvDh8rG6Lo57U1qHkQf2egifbXzN-8,2027
|
36
35
|
omlish/bootstrap/main.py,sha256=ZNzbT1t_dI4MhCB7so0glINw5XONTehIO5cv3hyXN44,5218
|
37
36
|
omlish/bootstrap/sys.py,sha256=U0MFxO9tLFV3cdN5Y-Zrink6_45sFvzPUYQXyBk7-ns,8741
|
@@ -56,6 +55,10 @@ omlish/collections/cache/__init__.py,sha256=Cv8RX-Ehit3um0QLDq7uRDqJUCcdqTKoAB9T
|
|
56
55
|
omlish/collections/cache/descriptor.py,sha256=t-1Gh4DTABDuNmeDJlpoW4LV3gi_uSlBd9ZfBINfYCM,5023
|
57
56
|
omlish/collections/cache/impl.py,sha256=nQox5kChhns9h2a5gnX-ayQGBQJ5-B1aZkLQ2Aej19g,15137
|
58
57
|
omlish/collections/cache/types.py,sha256=yNjwd6CGyTJQdxN2CQxFqqBAlcs1Z7vvNV-aU1K7p8E,685
|
58
|
+
omlish/concurrent/__init__.py,sha256=9p-s8MvBEYDqHIoYU3OYoe-Nni22QdkW7nhZGEukJTM,197
|
59
|
+
omlish/concurrent/executors.py,sha256=FYKCDYYuj-OgMa8quLsA47SfFNX3KDJvRENVk8NDsrA,1292
|
60
|
+
omlish/concurrent/futures.py,sha256=J2s9wYURUskqRJiBbAR0PNEAp1pXbIMYldOVBTQduQY,4239
|
61
|
+
omlish/concurrent/threadlets.py,sha256=2fzXEp_KPqIY7uoa5Jk2DJ3bLMY73ZsnzgN5myGanwc,2034
|
59
62
|
omlish/configs/__init__.py,sha256=3uh09ezodTwkMI0nRmAMP0eEuJ_0VdF-LYyNmPjHiCE,77
|
60
63
|
omlish/configs/classes.py,sha256=GLbB8xKjHjjoUQRCUQm3nEjM8z1qNTx9gPV7ODSt5dg,1317
|
61
64
|
omlish/configs/flattening.py,sha256=AOlRpBHm449MxwMp3CiIRGunStOC1DUNs1f3CLou0wc,4731
|
@@ -68,17 +71,17 @@ omlish/dataclasses/impl/as_.py,sha256=CD-t7hkC1EP2F_jvZKIA_cVoDuwZ-Ln_xC4fJumPYX
|
|
68
71
|
omlish/dataclasses/impl/copy.py,sha256=Tn8_n6Vohs-w4otbGdubBEvhd3TsSTaM3EfNGdS2LYo,591
|
69
72
|
omlish/dataclasses/impl/descriptors.py,sha256=rEYE1Len99agTQCC25hSPMnM19BgPr0ZChABGi58Fdk,2476
|
70
73
|
omlish/dataclasses/impl/exceptions.py,sha256=WD0Tr1TnjUN4OR3f3rs8CgqtP2KBA1tKjPIbZO8Tzm0,178
|
71
|
-
omlish/dataclasses/impl/fields.py,sha256=
|
72
|
-
omlish/dataclasses/impl/frozen.py,sha256=
|
74
|
+
omlish/dataclasses/impl/fields.py,sha256=6Ry-fTntJEPigSHBtaegssxeOi0L4hffLSL4SMtqjSE,5908
|
75
|
+
omlish/dataclasses/impl/frozen.py,sha256=x87DSM8FIMZ3c_BIUE8NooCkExFjPsabeqIueEP5qKs,2988
|
73
76
|
omlish/dataclasses/impl/hashing.py,sha256=FKnHuXCg9ylrzK2TLGqO5yfRN4HX3F415CSLlVYXtYE,3190
|
74
77
|
omlish/dataclasses/impl/init.py,sha256=yw9iInFHaR_TFWRzsryr8vgStHMQwqubL-s7pY5k1sA,5652
|
75
78
|
omlish/dataclasses/impl/internals.py,sha256=LTCqGT8AhyGTWwioGrBpTJzDzPvAtizQKb0NBNKcNs0,2989
|
76
|
-
omlish/dataclasses/impl/main.py,sha256=
|
79
|
+
omlish/dataclasses/impl/main.py,sha256=Ti0PKbFKraKvfmoPuR-G7nLVNzRC8mvEuXhCuC-M2kc,2574
|
77
80
|
omlish/dataclasses/impl/metaclass.py,sha256=dlQEIN9MHBirll7Nx3StpzxYxXjrqxJ-QsorMcCNt7w,2828
|
78
81
|
omlish/dataclasses/impl/metadata.py,sha256=binwdG0cyKdGEypRKYTbcDyH_be4aTaSnVnK2V5rwB8,1402
|
79
82
|
omlish/dataclasses/impl/order.py,sha256=zWvWDkSTym8cc7vO1cLHqcBhhjOlucHOCUVJcdh4jt0,1369
|
80
83
|
omlish/dataclasses/impl/params.py,sha256=M-xg9IeFftVy795oqlp7Yw8jE-7wG2K4vaFhXHKmL1k,2538
|
81
|
-
omlish/dataclasses/impl/processing.py,sha256=
|
84
|
+
omlish/dataclasses/impl/processing.py,sha256=DFxyFjL_h3awRyF_5eyTnB8QkuApx7Zc4QFnVoltlao,459
|
82
85
|
omlish/dataclasses/impl/reflect.py,sha256=13af257_sjjM-4wfH84nl7CoHHMV_eFZpkIgUawZ3TE,5307
|
83
86
|
omlish/dataclasses/impl/replace.py,sha256=wS9GHX4fIwaPv1JBJzIewdBfXyK3X3V7_t55Da87dYo,1217
|
84
87
|
omlish/dataclasses/impl/repr.py,sha256=oLXBTxqp88NKmz82HrJeGiTEiwK4l5LlXQT9Q0-tX3c,1605
|
@@ -156,17 +159,17 @@ omlish/inject/impl/proxy.py,sha256=1ko0VaKqzu9UG8bIldp9xtUrAVUOFTKWKTjOCqIGr4s,1
|
|
156
159
|
omlish/inject/impl/scopes.py,sha256=M_RO_pGUr5mX84YyYmkr6CsMhkkV189_gOUsaYmYes4,5768
|
157
160
|
omlish/lang/__init__.py,sha256=sjeN4p46itXbYfYJNqgin8olSU62xD700Af_vlgWiwI,3165
|
158
161
|
omlish/lang/cached.py,sha256=0gjdxVELu69oRQ3kqSV3cGIHg6Nf4pcCIIRTEU52tCc,7607
|
159
|
-
omlish/lang/clsdct.py,sha256=
|
162
|
+
omlish/lang/clsdct.py,sha256=AjtIWLlx2E6D5rC97zQ3Lwq2SOMkbg08pdO_AxpzEHI,1744
|
160
163
|
omlish/lang/cmp.py,sha256=5vbzWWbqdzDmNKAGL19z6ZfUKe5Ci49e-Oegf9f4BsE,1346
|
161
|
-
omlish/lang/contextmanagers.py,sha256=
|
162
|
-
omlish/lang/descriptors.py,sha256=
|
164
|
+
omlish/lang/contextmanagers.py,sha256=rzMSwJU7ObFXl46r6pGDbD45Zi_qZ9NHxDPnLNuux9o,9732
|
165
|
+
omlish/lang/descriptors.py,sha256=VGbebrhWR0WLe3SASN444lBBvAreVMcwdam1FjcRxkQ,5908
|
163
166
|
omlish/lang/exceptions.py,sha256=qJBo3NU1mOWWm-NhQUHCY5feYXR3arZVyEHinLsmRH4,47
|
164
|
-
omlish/lang/functions.py,sha256=
|
167
|
+
omlish/lang/functions.py,sha256=yJxWwqlXEAT2gied4uTwiz5x1qXeuVubOSXyn9zy5aI,3624
|
165
168
|
omlish/lang/imports.py,sha256=04ugFC8NI5sbL7NH4V0r0q_nFsP_AMkHLz697CVkMtQ,6274
|
166
169
|
omlish/lang/iterables.py,sha256=_q6rHbdFfW3VBqez0IV3rUABoNxsA_oBv_sykm5zsbQ,2243
|
167
170
|
omlish/lang/maybes.py,sha256=NYHZDjqDtwPMheDrj2VtUVujxRPf8Qpgk4ZlZCTvBZc,3492
|
168
|
-
omlish/lang/objects.py,sha256=
|
169
|
-
omlish/lang/resolving.py,sha256=
|
171
|
+
omlish/lang/objects.py,sha256=1dY8dX5voIZf5FBYUiN0BRsWg2JCdsgRbDl9fLG7OtY,4310
|
172
|
+
omlish/lang/resolving.py,sha256=OuN2mDTPNyBUbcrswtvFKtj4xgH4H4WglgqSKv3MTy0,1606
|
170
173
|
omlish/lang/strings.py,sha256=ykeoou4JK7CEZXzrUJfqVOalEDvE--j0uhHt_SrsrUs,2834
|
171
174
|
omlish/lang/sys.py,sha256=UoZz_PJYVKLQAKqYxxn-LHz1okK_38I__maZgnXMcxU,406
|
172
175
|
omlish/lang/timeouts.py,sha256=vECdWYhc_IZgcal1Ng1Y42wf2FV3KAx-i8As-MgGHIQ,1186
|
@@ -174,7 +177,7 @@ omlish/lang/typing.py,sha256=pKDBHTYzoQtFCUxtlDDTpnKixZBxeE5Pblvv1nJbRYE,3236
|
|
174
177
|
omlish/lang/classes/__init__.py,sha256=j1p0_uuMznKrY2EhMoj20uv6vx4LXljMzp7AaKe0mmU,530
|
175
178
|
omlish/lang/classes/abstract.py,sha256=goIV14oY24EOs88eVe6E6NyrSPOOLMOcWTXTMuYKiqc,2304
|
176
179
|
omlish/lang/classes/restrict.py,sha256=n_B-XqafVyO1caZzfbsv7tPxDJOBLl1BzQkoDSse0A4,3353
|
177
|
-
omlish/lang/classes/simple.py,sha256=
|
180
|
+
omlish/lang/classes/simple.py,sha256=_OE6-eph3-pllGck83FcGZE8fDMUqPdWP9OeSDCSgww,3071
|
178
181
|
omlish/lang/classes/virtual.py,sha256=54D4qOpDWHpP28Oc6bbBjdxquLvdvqMqLXj2XOnAeaQ,3323
|
179
182
|
omlish/lifecycles/__init__.py,sha256=1FjYceXs-4fc-S-C9zFYmc2axHs4znnQHcJVHdY7a6E,578
|
180
183
|
omlish/lifecycles/abstract.py,sha256=70CQyZy-c9a2o0ZJxPeUT7eYjWZTBrp2HpUBnrHdAOM,1109
|
@@ -190,16 +193,17 @@ omlish/lite/check.py,sha256=DR3Zj-7o4Y7pNheln68nN_BdX9zaotGQ2y8v97GDiWQ,535
|
|
190
193
|
omlish/lite/contextmanagers.py,sha256=HnQJiyrOmSvTL22XRJrFl5CLpCyHD9fsntEUAr9G-60,427
|
191
194
|
omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
|
192
195
|
omlish/lite/logs.py,sha256=qgP0pNjkoG5gjQ6xuXM7qpsLwZX3WbS7WaZlDqQKry4,2641
|
193
|
-
omlish/lite/marshal.py,sha256=
|
196
|
+
omlish/lite/marshal.py,sha256=u6jYUN_AndvI6__HJBvSw5ElHWC0CfHqgiDS28Vpqjg,8593
|
194
197
|
omlish/lite/reflect.py,sha256=9QYJwdINraq1JNMEgvoqeSlVvRRgOXpxAkpgX8EgRXc,1307
|
195
198
|
omlish/lite/runtime.py,sha256=VUhmNQvwf8QzkWSKj4Q0ReieJA_PzHaJNRBivfTseow,452
|
196
199
|
omlish/lite/secrets.py,sha256=FEc47dcU9M1CyMTnrihAAVwKf0ySZLahf83djOEDWXw,488
|
197
200
|
omlish/lite/strings.py,sha256=9dO_A6EkhcTZ2xmOUGSOMT-mx9BnoOzYu1-ocSrDJaA,670
|
198
201
|
omlish/lite/subprocesses.py,sha256=KuGV3ImehMjCUK0JoV3pUtG_7o5wei1lRDn9HxzByAg,3063
|
199
|
-
omlish/logs/__init__.py,sha256=
|
202
|
+
omlish/logs/__init__.py,sha256=E4m-RTIaTh0rT9ADY9iB1Yc3pYBcnmn-tfkWXsjRTW4,276
|
200
203
|
omlish/logs/_abc.py,sha256=UgrCUQVUi_PvT3p1CEkb3P74CFrFcZq2AFby3GEUv9M,5974
|
201
204
|
omlish/logs/configs.py,sha256=VfZjhyA4CeMYNhlsv5oD2IZ6Iv4d_lbUgZzcnLAkxNA,1052
|
202
205
|
omlish/logs/formatters.py,sha256=AFs9C6-qrFkgXZ0nL39wih_LGck1Tc79alvGyibBdQo,720
|
206
|
+
omlish/logs/handlers.py,sha256=nyuFgmO05By_Xwq7es58ClzS51-F53lJL7gD0x5IqAg,228
|
203
207
|
omlish/logs/noisy.py,sha256=8JORjI1dH38yU2MddM54OB6qt32Xozfocdb88vY4wro,335
|
204
208
|
omlish/logs/utils.py,sha256=MgGovbP0zUrZ3FGD3qYNQWn-l0jy0Y0bStcQvv5BOmQ,391
|
205
209
|
omlish/marshal/__init__.py,sha256=Co5UUlCyd3eDToQTOvTURmCICKzuULnR5B6ylgb2nFM,1515
|
@@ -236,13 +240,13 @@ omlish/reflect/types.py,sha256=R9AH5YnOvdZs6QhzJ6VmjvcvGibQEQi6YqK25f5VUxw,6862
|
|
236
240
|
omlish/secrets/__init__.py,sha256=VKB2IF9vz4h4RXcZxgXj36KXOLcGBzfqVnxPgPDWpmg,408
|
237
241
|
omlish/secrets/crypto.py,sha256=6CsLy0UEqCrBK8Xx_3-iFF6SKtu2GlEqUQ8-MliY3tk,3709
|
238
242
|
omlish/secrets/marshal.py,sha256=nVzsvQH5w3T2oMP7DCc1SLKxyR5e66psM57VOQoL0QA,2086
|
239
|
-
omlish/secrets/openssl.py,sha256=
|
243
|
+
omlish/secrets/openssl.py,sha256=wxA_wIlxtuOUy71ABxAJgavh-UI_taOfm-A0dVlmSwM,6219
|
240
244
|
omlish/secrets/passwords.py,sha256=3r-vEK6Gp6aq4L5Csnd06QnrjO9xfzHJP-g_7I9W_ao,4101
|
241
245
|
omlish/secrets/secrets.py,sha256=hFN82uYiBVx8YSE86leWNxb4IRp3qdwZPOi4w04h8u0,6855
|
242
246
|
omlish/secrets/subprocesses.py,sha256=EcnKlHHtnUMHGrBWXDfu8tv28wlgZx4P4GOiuPW9Vo8,1105
|
243
247
|
omlish/specs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
244
248
|
omlish/specs/jsonschema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
245
|
-
omlish/specs/jsonschema/types.py,sha256=
|
249
|
+
omlish/specs/jsonschema/types.py,sha256=qoxExgKfrI-UZXdk3qcVZIEyp1WckFbb85_eGInEoAY,467
|
246
250
|
omlish/specs/jsonschema/keywords/__init__.py,sha256=Zt2g1BXd654uU2AQ5P7_-x2Wrtf6cNbP9mxI1wGN4wo,596
|
247
251
|
omlish/specs/jsonschema/keywords/base.py,sha256=HA4OvsdvAl4o5JgJI_tuaHBGURjxT5QeFN6_ja5Z5xQ,1957
|
248
252
|
omlish/specs/jsonschema/keywords/core.py,sha256=irJ5Rreg9hTeXu3FovSdzhFb3vUly-hYQVYflEgST3g,368
|
@@ -285,8 +289,8 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
|
|
285
289
|
omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
|
286
290
|
omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
|
287
291
|
omlish/text/parts.py,sha256=KGgo0wHOIMVMZtDso-rhSWKAcAkYAH2IGpg9tULabu8,6505
|
288
|
-
omlish-0.0.0.
|
289
|
-
omlish-0.0.0.
|
290
|
-
omlish-0.0.0.
|
291
|
-
omlish-0.0.0.
|
292
|
-
omlish-0.0.0.
|
292
|
+
omlish-0.0.0.dev22.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
293
|
+
omlish-0.0.0.dev22.dist-info/METADATA,sha256=VLYWv2M6zOnFd6tjfwCF6zxknpq4PAREgFChwcGrM-4,3666
|
294
|
+
omlish-0.0.0.dev22.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
295
|
+
omlish-0.0.0.dev22.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
296
|
+
omlish-0.0.0.dev22.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|