omlish 0.0.0.dev103__py3-none-any.whl → 0.0.0.dev104__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.
@@ -0,0 +1,293 @@
1
+ """
2
+ TODO:
3
+ - https://docs.python.org/3/library/zlib.html#zlib.compressobj
4
+ """
5
+ import abc
6
+ import contextlib
7
+ import io
8
+ import typing as ta
9
+
10
+ from .. import check
11
+ from .. import lang
12
+ from ..concurrent import threadlets as tls
13
+ from ..sync import ConditionDeque
14
+
15
+
16
+ if ta.TYPE_CHECKING:
17
+ import threading
18
+
19
+ from . import pyio # noqa
20
+
21
+ else:
22
+ threading = lang.proxy_import('threading')
23
+
24
+ pyio = lang.proxy_import('.pyio', __package__)
25
+
26
+
27
+ T = ta.TypeVar('T')
28
+
29
+ BytesLike: ta.TypeAlias = ta.Any
30
+
31
+ BufferedReader = io.BufferedReader
32
+ # BufferedReader = pyio.BufferedReader
33
+
34
+
35
+ ##
36
+
37
+
38
+ class ProxyReadFile:
39
+ def __init__(self, read: ta.Callable[[int], bytes | BaseException]) -> None:
40
+ super().__init__()
41
+
42
+ self._read = read
43
+ self._eof = False
44
+ self._closed = False
45
+
46
+ #
47
+
48
+ def read(self, n: int, /) -> bytes:
49
+ if self._closed:
50
+ raise RuntimeError('Closed')
51
+ if self._eof:
52
+ return b''
53
+ d = self._read(n)
54
+ if isinstance(d, BaseException):
55
+ raise d
56
+ if not d:
57
+ self._eof = True
58
+ return d
59
+
60
+ def readall(self, *args, **kwargs):
61
+ raise TypeError # FIXME
62
+
63
+ def readinto(self, b: BytesLike) -> int | None:
64
+ d = self.read(len(b))
65
+ if d:
66
+ b[:len(d)] = d
67
+ return len(d)
68
+
69
+ #
70
+
71
+ def readable(self) -> bool:
72
+ return not (self._eof or self._closed)
73
+
74
+ @property
75
+ def closed(self) -> bool:
76
+ return self._closed
77
+
78
+ def close(self) -> None:
79
+ self._closed = True
80
+
81
+ #
82
+
83
+ def flush(self) -> None:
84
+ pass
85
+
86
+ def seekable(self) -> bool:
87
+ return False
88
+
89
+ def seek(self, n: int, /) -> ta.Any:
90
+ raise TypeError
91
+
92
+
93
+ ##
94
+
95
+
96
+ class NeedMore(lang.Marker):
97
+ pass
98
+
99
+
100
+ class Exited(lang.Marker):
101
+ pass
102
+
103
+
104
+ class Shutdown(BaseException): # noqa
105
+ pass
106
+
107
+
108
+ IoTrampolineTarget: ta.TypeAlias = ta.Callable[[io.BufferedReader], ta.ContextManager[ta.Callable[[], bytes]]]
109
+
110
+
111
+ class IoTrampoline(lang.Abstract):
112
+ def __init__(
113
+ self,
114
+ target: IoTrampolineTarget,
115
+ *,
116
+ buffer_size: int | None = None,
117
+ ) -> None:
118
+ super().__init__()
119
+
120
+ self._target = target
121
+ self._buffer_size = buffer_size
122
+
123
+ def _make_buffered_reader(self, raw: ta.Any) -> io.BufferedReader:
124
+ return io.BufferedReader(
125
+ raw,
126
+ **(dict(buffer_size=self._buffer_size) if self._buffer_size is not None else {}),
127
+ )
128
+
129
+ @abc.abstractmethod
130
+ def close(self, timeout: float | None = None) -> None:
131
+ raise NotImplementedError
132
+
133
+ @abc.abstractmethod
134
+ def __enter__(self) -> ta.Self:
135
+ raise NotImplementedError
136
+
137
+ @abc.abstractmethod
138
+ def __exit__(self, exc_type, exc_val, exc_tb):
139
+ raise NotImplementedError
140
+
141
+ @abc.abstractmethod
142
+ def feed(self, *data: bytes) -> ta.Iterable[bytes]:
143
+ raise NotImplementedError
144
+
145
+
146
+ #
147
+
148
+
149
+ class ThreadIoTrampoline(IoTrampoline):
150
+ def __init__(self, target: IoTrampolineTarget, **kwargs: ta.Any) -> None:
151
+ super().__init__(target, **kwargs)
152
+
153
+ self._in: ConditionDeque[bytes | BaseException] = ConditionDeque()
154
+ self._out: ConditionDeque[
155
+ bytes | # noqa
156
+ type[NeedMore] |
157
+ type[Exited] |
158
+ BaseException
159
+ ] = ConditionDeque()
160
+
161
+ self._proxy = ProxyReadFile(self._read)
162
+
163
+ self._thread = threading.Thread(target=self._thread_proc, daemon=True)
164
+
165
+ #
166
+
167
+ def close(self, timeout: float | None = None) -> None:
168
+ if not self._thread.is_alive():
169
+ return
170
+ self._out.push(Shutdown())
171
+ self._thread.join(timeout)
172
+ if self._thread.is_alive():
173
+ if timeout is not None:
174
+ raise TimeoutError
175
+ else:
176
+ raise RuntimeError('Failed to join thread')
177
+
178
+ #
179
+
180
+ def __enter__(self) -> ta.Self:
181
+ self._thread.start()
182
+ return self
183
+
184
+ def __exit__(self, exc_type, exc_val, exc_tb):
185
+ self.close()
186
+
187
+ #
188
+
189
+ def _read(self, n: int, /) -> bytes | BaseException:
190
+ return self._in.pop(if_empty=lambda: self._out.push(NeedMore))
191
+
192
+ def _thread_proc(self) -> None:
193
+ try:
194
+ with contextlib.closing(self._make_buffered_reader(self._proxy)) as bf: # noqa
195
+ with self._target(bf) as read:
196
+ while out := read():
197
+ self._out.push(out)
198
+ self._out.push(out)
199
+ except BaseException as e:
200
+ self._out.push(e)
201
+ raise
202
+ finally:
203
+ self._out.push(Exited)
204
+
205
+ def feed(self, *data: bytes) -> ta.Iterable[bytes]:
206
+ self._in.push(*data)
207
+ while True:
208
+ e = self._out.pop()
209
+ if e is NeedMore:
210
+ break
211
+ elif isinstance(e, BaseException):
212
+ raise e
213
+ elif e is Exited:
214
+ raise RuntimeError('IO thread exited')
215
+ elif isinstance(e, bytes):
216
+ yield e
217
+ if not e:
218
+ return
219
+ else:
220
+ raise TypeError(e)
221
+
222
+
223
+ #
224
+
225
+
226
+ class ThreadletIoTrampoline(IoTrampoline):
227
+ def __init__(
228
+ self,
229
+ target: IoTrampolineTarget,
230
+ threadlets: tls.Threadlets = tls.GREENLET_THREADLETS,
231
+ ** kwargs: ta.Any,
232
+ ) -> None:
233
+ super().__init__(target, **kwargs)
234
+
235
+ self._proxy = ProxyReadFile(self._read)
236
+ self._tl: tls.Threadlet = threadlets.spawn(self._g_proc)
237
+
238
+ #
239
+
240
+ def close(self, timeout: float | None = None) -> None:
241
+ if self._tl.dead:
242
+ return
243
+ out = self._tl.switch(Shutdown())
244
+ if out is not Exited or not self._tl.dead:
245
+ raise RuntimeError
246
+
247
+ #
248
+
249
+ def __enter__(self) -> ta.Self:
250
+ out = self._tl.switch()
251
+ if out is not NeedMore:
252
+ raise RuntimeError
253
+ return self
254
+
255
+ def __exit__(self, exc_type, exc_val, exc_tb):
256
+ self.close()
257
+
258
+ #
259
+
260
+ def _read(self, n: int, /) -> bytes:
261
+ out = check.not_none(self._tl.parent).switch(NeedMore)
262
+ return out
263
+
264
+ def _g_proc(self) -> ta.Any:
265
+ try:
266
+ with contextlib.closing(self._make_buffered_reader(self._proxy)) as bf: # noqa
267
+ with self._target(bf) as read:
268
+ while out := read():
269
+ e = check.not_none(self._tl.parent).switch(out)
270
+ if e is not NeedMore:
271
+ raise TypeError(e) # noqa
272
+ e = check.not_none(self._tl.parent).switch(out)
273
+ if not isinstance(e, Shutdown):
274
+ raise TypeError(e) # noqa
275
+ return Exited
276
+ except BaseException as e:
277
+ check.not_none(self._tl.parent).throw(e)
278
+ raise
279
+
280
+ def feed(self, *data: bytes) -> ta.Iterable[bytes]:
281
+ i: bytes | type[NeedMore]
282
+ for i in data:
283
+ while True:
284
+ e = self._tl.switch(i)
285
+ i = NeedMore
286
+ if e is NeedMore:
287
+ break
288
+ elif isinstance(e, bytes):
289
+ yield e
290
+ if not e:
291
+ return
292
+ else:
293
+ raise TypeError(e)
omlish/lite/marshal.py CHANGED
@@ -12,6 +12,8 @@ import datetime
12
12
  import decimal
13
13
  import enum
14
14
  import fractions
15
+ import functools
16
+ import threading
15
17
  import typing as ta
16
18
  import uuid
17
19
  import weakref # noqa
@@ -210,7 +212,10 @@ class UuidObjMarshaler(ObjMarshaler):
210
212
  return uuid.UUID(o)
211
213
 
212
214
 
213
- _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
215
+ ##
216
+
217
+
218
+ _DEFAULT_OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = {
214
219
  **{t: NopObjMarshaler() for t in (type(None),)},
215
220
  **{t: CastObjMarshaler(t) for t in (int, float, str, bool)},
216
221
  **{t: Base64ObjMarshaler(t) for t in (bytes, bytearray)},
@@ -239,20 +244,19 @@ _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES: ta.Dict[ta.Any, type] = {
239
244
  }
240
245
 
241
246
 
242
- def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
243
- if ty in _OBJ_MARSHALERS:
244
- raise KeyError(ty)
245
- _OBJ_MARSHALERS[ty] = m
246
-
247
-
248
- def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
247
+ def _make_obj_marshaler(
248
+ ty: ta.Any,
249
+ rec: ta.Callable[[ta.Any], ObjMarshaler],
250
+ *,
251
+ nonstrict_dataclasses: bool = False,
252
+ ) -> ObjMarshaler:
249
253
  if isinstance(ty, type):
250
254
  if abc.ABC in ty.__bases__:
251
255
  impls = [ # type: ignore
252
256
  PolymorphicObjMarshaler.Impl(
253
257
  ity,
254
258
  ity.__qualname__,
255
- get_obj_marshaler(ity),
259
+ rec(ity),
256
260
  )
257
261
  for ity in deep_subclasses(ty)
258
262
  if abc.ABC not in ity.__bases__
@@ -268,7 +272,8 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
268
272
  if dc.is_dataclass(ty):
269
273
  return DataclassObjMarshaler(
270
274
  ty,
271
- {f.name: get_obj_marshaler(f.type) for f in dc.fields(ty)},
275
+ {f.name: rec(f.type) for f in dc.fields(ty)},
276
+ nonstrict=nonstrict_dataclasses,
272
277
  )
273
278
 
274
279
  if is_generic_alias(ty):
@@ -278,7 +283,7 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
278
283
  pass
279
284
  else:
280
285
  k, v = ta.get_args(ty)
281
- return MappingObjMarshaler(mt, get_obj_marshaler(k), get_obj_marshaler(v))
286
+ return MappingObjMarshaler(mt, rec(k), rec(v))
282
287
 
283
288
  try:
284
289
  st = _OBJ_MARSHALER_GENERIC_ITERABLE_TYPES[ta.get_origin(ty)]
@@ -286,33 +291,71 @@ def _make_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
286
291
  pass
287
292
  else:
288
293
  [e] = ta.get_args(ty)
289
- return IterableObjMarshaler(st, get_obj_marshaler(e))
294
+ return IterableObjMarshaler(st, rec(e))
290
295
 
291
296
  if is_union_alias(ty):
292
- return OptionalObjMarshaler(get_obj_marshaler(get_optional_alias_arg(ty)))
297
+ return OptionalObjMarshaler(rec(get_optional_alias_arg(ty)))
293
298
 
294
299
  raise TypeError(ty)
295
300
 
296
301
 
297
- def get_obj_marshaler(ty: ta.Any) -> ObjMarshaler:
298
- try:
299
- return _OBJ_MARSHALERS[ty]
300
- except KeyError:
301
- pass
302
-
303
- p = ProxyObjMarshaler()
304
- _OBJ_MARSHALERS[ty] = p
305
- try:
306
- m = _make_obj_marshaler(ty)
307
- except Exception:
308
- del _OBJ_MARSHALERS[ty]
309
- raise
310
- else:
311
- p.m = m
302
+ ##
303
+
304
+
305
+ _OBJ_MARSHALERS_LOCK = threading.RLock()
306
+
307
+ _OBJ_MARSHALERS: ta.Dict[ta.Any, ObjMarshaler] = dict(_DEFAULT_OBJ_MARSHALERS)
308
+
309
+ _OBJ_MARSHALER_PROXIES: ta.Dict[ta.Any, ProxyObjMarshaler] = {}
310
+
311
+
312
+ def register_opj_marshaler(ty: ta.Any, m: ObjMarshaler) -> None:
313
+ with _OBJ_MARSHALERS_LOCK:
314
+ if ty in _OBJ_MARSHALERS:
315
+ raise KeyError(ty)
312
316
  _OBJ_MARSHALERS[ty] = m
317
+
318
+
319
+ def get_obj_marshaler(
320
+ ty: ta.Any,
321
+ *,
322
+ no_cache: bool = False,
323
+ **kwargs: ta.Any,
324
+ ) -> ObjMarshaler:
325
+ with _OBJ_MARSHALERS_LOCK:
326
+ if not no_cache:
327
+ try:
328
+ return _OBJ_MARSHALERS[ty]
329
+ except KeyError:
330
+ pass
331
+
332
+ try:
333
+ return _OBJ_MARSHALER_PROXIES[ty]
334
+ except KeyError:
335
+ pass
336
+
337
+ rec = functools.partial(
338
+ get_obj_marshaler,
339
+ no_cache=no_cache,
340
+ **kwargs,
341
+ )
342
+
343
+ p = ProxyObjMarshaler()
344
+ _OBJ_MARSHALER_PROXIES[ty] = p
345
+ try:
346
+ m = _make_obj_marshaler(ty, rec, **kwargs)
347
+ finally:
348
+ del _OBJ_MARSHALER_PROXIES[ty]
349
+ p.m = m
350
+
351
+ if not no_cache:
352
+ _OBJ_MARSHALERS[ty] = m
313
353
  return m
314
354
 
315
355
 
356
+ ##
357
+
358
+
316
359
  def marshal_obj(o: ta.Any, ty: ta.Any = None) -> ta.Any:
317
360
  return get_obj_marshaler(ty if ty is not None else type(o)).marshal(o)
318
361
 
omlish/specs/__init__.py CHANGED
@@ -4,6 +4,8 @@ TODO:
4
4
  - iceberg
5
5
  - jsonnet
6
6
  - jsonpatch
7
+ - jsonpath
7
8
  - jsonpointer.py
8
9
  - protobuf
10
+ - irc? or in net?
9
11
  """
omlish/sync.py CHANGED
@@ -3,6 +3,7 @@ TODO:
3
3
  - sync (lol) w/ asyncs.anyio
4
4
  - atomics
5
5
  """
6
+ import collections
6
7
  import threading
7
8
  import typing as ta
8
9
 
@@ -68,3 +69,57 @@ class LazyFn(ta.Generic[T]):
68
69
  self._v = lang.just(self._fn())
69
70
  self._once.do(do)
70
71
  return self._v.must()
72
+
73
+
74
+ class ConditionDeque(ta.Generic[T]):
75
+ def __init__(
76
+ self,
77
+ *,
78
+ cond: ta.Optional['threading.Condition'] = None,
79
+ deque: collections.deque[T] | None = None,
80
+
81
+ lock: ta.Optional['threading.RLock'] = None,
82
+ maxlen: int | None = None,
83
+ init: ta.Iterable[T] | None = None,
84
+ ) -> None:
85
+ super().__init__()
86
+
87
+ if cond is None:
88
+ cond = threading.Condition(lock=lock)
89
+ if deque is None:
90
+ deque = collections.deque(maxlen=maxlen)
91
+ if init:
92
+ deque.extend(init)
93
+
94
+ self._cond = cond
95
+ self._deque = deque
96
+
97
+ @property
98
+ def cond(self) -> 'threading.Condition':
99
+ return self._cond
100
+
101
+ @property
102
+ def deque(self) -> collections.deque[T]:
103
+ return self._deque
104
+
105
+ def push(
106
+ self,
107
+ *items: T,
108
+ n: int = 1,
109
+ ) -> None:
110
+ with self.cond:
111
+ self.deque.extend(items)
112
+ self.cond.notify(n)
113
+
114
+ def pop(
115
+ self,
116
+ timeout: float | None = None,
117
+ *,
118
+ if_empty: ta.Callable[[], None] | None = None,
119
+ ) -> T:
120
+ with self.cond:
121
+ if not self.deque and if_empty is not None:
122
+ if_empty()
123
+ while not self.deque:
124
+ self.cond.wait(timeout)
125
+ return self.deque.popleft()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev103
3
+ Version: 0.0.0.dev104
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=hTFp9tvE72BxKloIq1s1SS0LRQlIsvMtO69Sbc47rKg,1704
2
- omlish/__about__.py,sha256=2FoZ6Jc4EVw0ktjCpXD7hwO_dcHH4tOlvoj9GJedqdM,3352
2
+ omlish/__about__.py,sha256=eXMJ1X3ac5DhIwcFjhLaDOtcyXblPwi6wDohYlBKyHc,3352
3
3
  omlish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  omlish/argparse.py,sha256=Dc73G8lyoQBLvXhMYUbzQUh4SJu_OTvKUXjSUxq_ang,7499
5
5
  omlish/c3.py,sha256=4vogWgwPb8TbNS2KkZxpoWbwjj7MuHG2lQG-hdtkvjI,8062
@@ -8,7 +8,7 @@ omlish/check.py,sha256=rZFEn6IHiMq4KGCYxlUGcUCJP12pPPUs_-AG0aouPM8,10540
8
8
  omlish/datetimes.py,sha256=HajeM1kBvwlTa-uR1TTZHmZ3zTPnnUr1uGGQhiO1XQ0,2152
9
9
  omlish/defs.py,sha256=T3bq_7h_tO3nDB5RAFBn7DkdeQgqheXzkFColbOHZko,4890
10
10
  omlish/dynamic.py,sha256=35C_cCX_Vq2HrHzGk5T-zbrMvmUdiIiwDzDNixczoDo,6541
11
- omlish/fnpairs.py,sha256=vCuZqLz2IAM3PDaJQE3r1A4EjyrCyUNoCOjoa_SmKCU,10723
11
+ omlish/fnpairs.py,sha256=hLCjbwZ0cVGPmTaw_NMpMau0KpjYEB6kKzI_mNgoKnk,10778
12
12
  omlish/fnpipes.py,sha256=AJkgz9nvRRm7oqw7ZgYyz21klu276LWi54oYCLg-vOg,2196
13
13
  omlish/genmachine.py,sha256=RlU-y_dt2nRdvoo7Z3HsUELlBn3KuyI4qUnqLVbChRI,2450
14
14
  omlish/iterators.py,sha256=GGLC7RIT86uXMjhIIIqnff_Iu5SI_b9rXYywYGFyzmo,7292
@@ -17,7 +17,7 @@ omlish/matchfns.py,sha256=I1IlQGfEyk_AcFSy6ulVS3utC-uwyZM2YfUXYHc9Bw0,6152
17
17
  omlish/multiprocessing.py,sha256=QZT4C7I-uThCAjaEY3xgUYb-5GagUlnE4etN01LDyU4,5186
18
18
  omlish/os.py,sha256=5nJ-a9JKSMoaZVZ1eOa5BAbfL7o7CF7ue_PyJwufnwY,1460
19
19
  omlish/runmodule.py,sha256=PWvuAaJ9wQQn6bx9ftEL3_d04DyotNn8dR_twm2pgw0,700
20
- omlish/sync.py,sha256=AqwIfIuCMVHLwlJUa7dmaSjfA4sM5AYPCD5-nsz3XVQ,1516
20
+ omlish/sync.py,sha256=QJ79kxmIqDP9SeHDoZAf--DpFIhDQe1jACy8H4N0yZI,2928
21
21
  omlish/term.py,sha256=BXJSE9gfM461bh4z_gysx0oavZSafqcQs5ayZK-kTUo,9284
22
22
  omlish/antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
23
  omlish/antlr/_runtime/BufferedTokenStream.py,sha256=1Rnhm62MZCWSuQeRs7lRUbdtdyo7Gyg8r4gAETjv-cE,10793
@@ -119,7 +119,7 @@ omlish/collections/cache/types.py,sha256=yNjwd6CGyTJQdxN2CQxFqqBAlcs1Z7vvNV-aU1K
119
119
  omlish/concurrent/__init__.py,sha256=9p-s8MvBEYDqHIoYU3OYoe-Nni22QdkW7nhZGEukJTM,197
120
120
  omlish/concurrent/executors.py,sha256=FYKCDYYuj-OgMa8quLsA47SfFNX3KDJvRENVk8NDsrA,1292
121
121
  omlish/concurrent/futures.py,sha256=J2s9wYURUskqRJiBbAR0PNEAp1pXbIMYldOVBTQduQY,4239
122
- omlish/concurrent/threadlets.py,sha256=rTuGp4odJv23eiGTR0E73_gXKgjh4AOeRhutUcEFh70,2378
122
+ omlish/concurrent/threadlets.py,sha256=JfirbTDJgy9Ouokz_VmHeAAPS7cih8qMUJrN-owwXD4,2423
123
123
  omlish/configs/__init__.py,sha256=3uh09ezodTwkMI0nRmAMP0eEuJ_0VdF-LYyNmPjHiCE,77
124
124
  omlish/configs/classes.py,sha256=GLbB8xKjHjjoUQRCUQm3nEjM8z1qNTx9gPV7ODSt5dg,1317
125
125
  omlish/configs/flattening.py,sha256=AOlRpBHm449MxwMp3CiIRGunStOC1DUNs1f3CLou0wc,4731
@@ -198,8 +198,9 @@ omlish/formats/json/backends/std.py,sha256=PM00Kh9ZR2XzollHMEvdo35Eml1N-zFfRW-LO
198
198
  omlish/formats/json/backends/ujson.py,sha256=BNJCU4kluGHdqTUKLJEuHhE2m2TmqR7HEN289S0Eokg,2278
199
199
  omlish/formats/json/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
200
200
  omlish/formats/json/cli/__main__.py,sha256=1wxxKZVkj_u7HCcewwMIbGuZj_Wph95yrUbm474Op9M,188
201
- omlish/formats/json/cli/cli.py,sha256=Ka-S-_L79HjaqbIi1SbGDywbYtEtoo673_DIG9m14jM,6027
202
- omlish/formats/json/cli/formats.py,sha256=tqEZKby4HeafGcaUs-m8B-2ZV12dRo40rzL-V99cp00,1714
201
+ omlish/formats/json/cli/cli.py,sha256=RoyZPSoIZ5aJxWeMQlUom_MhqwE58Vcg9HV8AIRNot8,8113
202
+ omlish/formats/json/cli/formats.py,sha256=FUZ0ptn3n0ljei2_o0t5UtmZkMB3_5p1pE-hgDD3-ak,1721
203
+ omlish/formats/json/cli/io.py,sha256=IoJ5asjS_gUan5TcrGgS0KpJaiSE5YQgEGljFMCcDto,1427
203
204
  omlish/formats/json/stream/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
204
205
  omlish/formats/json/stream/build.py,sha256=6deXBxTx1toFAPShz2Jo5OiXxH5Y4ppG8gDPRFoUgjA,2461
205
206
  omlish/formats/json/stream/lex.py,sha256=_JYoWFRpo3_dQmT7xXCWGFNoBT4M8m97G9oGzwPZeo4,6483
@@ -217,12 +218,13 @@ omlish/graphs/dot/utils.py,sha256=_FMwn77WfiiAfLsRTOKWm4IYbNv5kQN22YJ5psw6CWg,80
217
218
  omlish/http/__init__.py,sha256=OqCovZi_jv1Mnk975idaXA8FCGy4laoQIvNZ3hdKpRQ,722
218
219
  omlish/http/asgi.py,sha256=wXhBZ21bEl32Kv9yBrRwUR_7pHEgVtHP8ZZwbasQ6-4,3307
219
220
  omlish/http/clients.py,sha256=WRtCNIt9Y790xpem69HiXJY9W-vPlpGPKZwpHusa2EE,6280
220
- omlish/http/consts.py,sha256=FTolezLknKU6WJjk_x2T3a5LEMlnZSqv7gzTq55lxcU,2147
221
+ omlish/http/consts.py,sha256=s-3GgSt1-mJLdQYe8nZ3-OwycMSPj3aCTLSukZcPjXs,2216
221
222
  omlish/http/cookies.py,sha256=uuOYlHR6e2SC3GM41V0aozK10nef9tYg83Scqpn5-HM,6351
222
223
  omlish/http/dates.py,sha256=Otgp8wRxPgNGyzx8LFowu1vC4EKJYARCiAwLFncpfHM,2875
223
224
  omlish/http/encodings.py,sha256=w2WoKajpaZnQH8j-IBvk5ZFL2O2pAU_iBvZnkocaTlw,164
224
225
  omlish/http/headers.py,sha256=ZMmjrEiYjzo0YTGyK0YsvjdwUazktGqzVVYorY4fd44,5081
225
226
  omlish/http/json.py,sha256=9XwAsl4966Mxrv-1ytyCqhcE6lbBJw-0_tFZzGszgHE,7440
227
+ omlish/http/jwt.py,sha256=6Rigk1WrJ059DY4jDIKnxjnChWb7aFdermj2AI2DSvk,4346
226
228
  omlish/http/multipart.py,sha256=R9ycpHsXRcmh0uoc43aYb7BdWL-8kSQHe7J-M81aQZM,2240
227
229
  omlish/http/sessions.py,sha256=VZ_WS5uiQG5y7i3u8oKuQMqf8dPKUOjFm_qk_0OvI8c,4793
228
230
  omlish/http/sse.py,sha256=MDs9RvxQXoQliImcc6qK1ERajEYM7Q1l8xmr-9ceNBc,2315
@@ -257,6 +259,9 @@ omlish/inject/impl/privates.py,sha256=alpCYyk5VJ9lJknbRH2nLVNFYVvFhkj-VC1Vco3zCF
257
259
  omlish/inject/impl/providers.py,sha256=QnwhsujJFIHC0JTgd2Wlo1kP53i3CWTrj1nKU2DNxwg,2375
258
260
  omlish/inject/impl/proxy.py,sha256=1ko0VaKqzu9UG8bIldp9xtUrAVUOFTKWKTjOCqIGr4s,1636
259
261
  omlish/inject/impl/scopes.py,sha256=ASfULXgP_ETlsAqFJfrZmyEaZt64Zr8tNn5ScA-EoXk,5900
262
+ omlish/io/__init__.py,sha256=aaIEsXTSfytW-oEkUWczdUJ_ifFY7ihIpyidIbfjkwY,56
263
+ omlish/io/pyio.py,sha256=YB3g6yg64MzcFwbzKBo4adnbsbZ3FZMlOZfjNtWmYoc,95316
264
+ omlish/io/trampoline.py,sha256=pOwCtwPtLiwdA3JAN5vopv2ZlzKOhllrXg1ltvaEVAc,7249
260
265
  omlish/lang/__init__.py,sha256=1BTfyRGPq8ahztMT3xP34EcN2zV3bInCqc1XrUygZh8,3704
261
266
  omlish/lang/cached.py,sha256=92TvRZQ6sWlm7dNn4hgl7aWKbX0J1XUEo3DRjBpgVQk,7834
262
267
  omlish/lang/clsdct.py,sha256=AjtIWLlx2E6D5rC97zQ3Lwq2SOMkbg08pdO_AxpzEHI,1744
@@ -296,7 +301,7 @@ omlish/lite/contextmanagers.py,sha256=_n6a9xhn06BD8H6A_SDtcipMrSBpzBqcxI0Ob2juom
296
301
  omlish/lite/io.py,sha256=lcpI1cS_Kn90tvYMg8ZWkSlYloS4RFqXCk-rKyclhdg,3148
297
302
  omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
298
303
  omlish/lite/logs.py,sha256=vkFkSX0Izb2P-NNMqqNLSec0BzeLOtHoQWgdXwQuDPU,6007
299
- omlish/lite/marshal.py,sha256=NPy2eV6wDMIhE8ZBSN6kDeOCt0aU46c53o-7QIhp-DI,8660
304
+ omlish/lite/marshal.py,sha256=SyYMsJ-TaGO9FX7LykBB0WtqsqetX9eLBotPiz3M_xg,9478
300
305
  omlish/lite/pidfile.py,sha256=PRSDOAXmNkNwxh-Vwif0Nrs8RAmWroiNhLKIbdjwzBc,1723
301
306
  omlish/lite/reflect.py,sha256=9QYJwdINraq1JNMEgvoqeSlVvRRgOXpxAkpgX8EgRXc,1307
302
307
  omlish/lite/runtime.py,sha256=VUhmNQvwf8QzkWSKj4Q0ReieJA_PzHaJNRBivfTseow,452
@@ -356,7 +361,7 @@ omlish/secrets/pwgen.py,sha256=v-5ztnOTHTAWXLGR-3H6HkMj2nPIZBMbo5xWR3q0rDY,1707
356
361
  omlish/secrets/pwhash.py,sha256=3r-vEK6Gp6aq4L5Csnd06QnrjO9xfzHJP-g_7I9W_ao,4101
357
362
  omlish/secrets/secrets.py,sha256=cnDGBoPknVxsCN04_gqcJT_7Ebk3iO3VPkRZ2oMjkMw,7868
358
363
  omlish/secrets/subprocesses.py,sha256=EcnKlHHtnUMHGrBWXDfu8tv28wlgZx4P4GOiuPW9Vo8,1105
359
- omlish/specs/__init__.py,sha256=Xl4fT1o1MlcEIAjMt5EifgMuO4UBSa9Suj5NE9eMX1A,87
364
+ omlish/specs/__init__.py,sha256=zZwF8yXTEkSstYtORkDhVLK-_hWU8WOJCuBpognb_NY,118
360
365
  omlish/specs/jmespath/LICENSE,sha256=IH-ZZlZkS8XMkf_ubNVD1aYHQ2l_wd0tmHtXrCcYpRU,1113
361
366
  omlish/specs/jmespath/__init__.py,sha256=Lz8JO0vP-pwrBtq9Y94y6LrOA7o1u1kCdPmMf_4lJBY,1918
362
367
  omlish/specs/jmespath/__main__.py,sha256=wIXm6bs08etNG_GZlN2rBkADPb0rKfL2HSkm8spnpxw,200
@@ -458,9 +463,9 @@ omlish/text/delimit.py,sha256=ubPXcXQmtbOVrUsNh5gH1mDq5H-n1y2R4cPL5_DQf68,4928
458
463
  omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,3296
459
464
  omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
460
465
  omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
461
- omlish-0.0.0.dev103.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
462
- omlish-0.0.0.dev103.dist-info/METADATA,sha256=xpRaIXI0C7A878exoxOF6Ntzr0NWU3R66b_5MQ6BuPY,4000
463
- omlish-0.0.0.dev103.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
464
- omlish-0.0.0.dev103.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
465
- omlish-0.0.0.dev103.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
466
- omlish-0.0.0.dev103.dist-info/RECORD,,
466
+ omlish-0.0.0.dev104.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
467
+ omlish-0.0.0.dev104.dist-info/METADATA,sha256=vPlEUQb7V6eq66MyHSmmlwUQ342OOUE6jdSxnzBolxw,4000
468
+ omlish-0.0.0.dev104.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
469
+ omlish-0.0.0.dev104.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
470
+ omlish-0.0.0.dev104.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
471
+ omlish-0.0.0.dev104.dist-info/RECORD,,