omlish 0.0.0.dev151__py3-none-any.whl → 0.0.0.dev153__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev151'
2
- __revision__ = '7d978888ef2b04964976a01388376b919ec8bafe'
1
+ __version__ = '0.0.0.dev153'
2
+ __revision__ = '98ab8eed12f9cf5fa241294e648759c21741ad57'
3
3
 
4
4
 
5
5
  #
omlish/argparse/cli.py CHANGED
@@ -4,6 +4,8 @@
4
4
  TODO:
5
5
  - default command
6
6
  - auto match all underscores to hyphens
7
+ - pre-run, post-run hooks
8
+ - exitstack?
7
9
  """
8
10
  import argparse
9
11
  import dataclasses as dc
@@ -136,11 +138,12 @@ class ArgparseCli:
136
138
 
137
139
  self._args, self._unknown_args = self.get_parser().parse_known_args(self._argv)
138
140
 
141
+ #
142
+
139
143
  def __init_subclass__(cls, **kwargs: ta.Any) -> None:
140
144
  super().__init_subclass__(**kwargs)
141
145
 
142
146
  ns = cls.__dict__
143
-
144
147
  objs = {}
145
148
  mro = cls.__mro__[::-1]
146
149
  for bns in [bcls.__dict__ for bcls in reversed(mro)] + [ns]:
@@ -153,24 +156,33 @@ class ArgparseCli:
153
156
  elif k in objs:
154
157
  del [k]
155
158
 
159
+ #
160
+
156
161
  anns = ta.get_type_hints(_ArgparseCliAnnotationBox({
157
162
  **{k: v for bcls in reversed(mro) for k, v in getattr(bcls, '__annotations__', {}).items()},
158
163
  **ns.get('__annotations__', {}),
159
164
  }), globalns=ns.get('__globals__', {}))
160
165
 
166
+ #
167
+
161
168
  if '_parser' in ns:
162
169
  parser = check.isinstance(ns['_parser'], argparse.ArgumentParser)
163
170
  else:
164
171
  parser = argparse.ArgumentParser()
165
172
  setattr(cls, '_parser', parser)
166
173
 
174
+ #
175
+
167
176
  subparsers = parser.add_subparsers()
177
+
168
178
  for att, obj in objs.items():
169
179
  if isinstance(obj, ArgparseCommand):
170
180
  if obj.parent is not None:
171
181
  raise NotImplementedError
182
+
172
183
  for cn in [obj.name, *(obj.aliases or [])]:
173
- cparser = subparsers.add_parser(cn)
184
+ subparser = subparsers.add_parser(cn)
185
+
174
186
  for arg in (obj.args or []):
175
187
  if (
176
188
  len(arg.args) == 1 and
@@ -178,29 +190,34 @@ class ArgparseCli:
178
190
  not (n := check.isinstance(arg.args[0], str)).startswith('-') and
179
191
  'metavar' not in arg.kwargs
180
192
  ):
181
- cparser.add_argument(
193
+ subparser.add_argument(
182
194
  n.replace('-', '_'),
183
195
  **arg.kwargs,
184
196
  metavar=n,
185
197
  )
186
198
  else:
187
- cparser.add_argument(*arg.args, **arg.kwargs)
188
- cparser.set_defaults(_cmd=obj)
199
+ subparser.add_argument(*arg.args, **arg.kwargs)
200
+
201
+ subparser.set_defaults(_cmd=obj)
189
202
 
190
203
  elif isinstance(obj, ArgparseArg):
191
204
  if att in anns:
192
- akwargs = _get_argparse_arg_ann_kwargs(anns[att])
193
- obj.kwargs = {**akwargs, **obj.kwargs}
205
+ ann_kwargs = _get_argparse_arg_ann_kwargs(anns[att])
206
+ obj.kwargs = {**ann_kwargs, **obj.kwargs}
207
+
194
208
  if not obj.dest:
195
209
  if 'dest' in obj.kwargs:
196
210
  obj.dest = obj.kwargs['dest']
197
211
  else:
198
212
  obj.dest = obj.kwargs['dest'] = att # type: ignore
213
+
199
214
  parser.add_argument(*obj.args, **obj.kwargs)
200
215
 
201
216
  else:
202
217
  raise TypeError(obj)
203
218
 
219
+ #
220
+
204
221
  _parser: ta.ClassVar[argparse.ArgumentParser]
205
222
 
206
223
  @classmethod
@@ -219,10 +236,12 @@ class ArgparseCli:
219
236
  def unknown_args(self) -> ta.Sequence[str]:
220
237
  return self._unknown_args
221
238
 
222
- def _run_cmd(self, cmd: ArgparseCommand) -> ta.Optional[int]:
223
- return cmd.__get__(self, type(self))()
239
+ #
240
+
241
+ def _bind_cli_cmd(self, cmd: ArgparseCommand) -> ta.Callable:
242
+ return cmd.__get__(self, type(self))
224
243
 
225
- def __call__(self) -> ta.Optional[int]:
244
+ def prepare_cli_run(self) -> ta.Optional[ta.Callable]:
226
245
  cmd = getattr(self.args, '_cmd', None)
227
246
 
228
247
  if self._unknown_args and not (cmd is not None and cmd.accepts_unknown):
@@ -234,9 +253,31 @@ class ArgparseCli:
234
253
 
235
254
  if cmd is None:
236
255
  self.get_parser().print_help()
256
+ return None
257
+
258
+ return self._bind_cli_cmd(cmd)
259
+
260
+ #
261
+
262
+ def cli_run(self) -> ta.Optional[int]:
263
+ if (fn := self.prepare_cli_run()) is None:
237
264
  return 0
238
265
 
239
- return self._run_cmd(cmd)
266
+ return fn()
267
+
268
+ def cli_run_and_exit(self) -> ta.NoReturn:
269
+ sys.exit(rc if isinstance(rc := self.cli_run(), int) else 0)
270
+
271
+ def __call__(self, *, exit: bool = False) -> ta.Optional[int]: # noqa
272
+ if exit:
273
+ return self.cli_run_and_exit()
274
+ else:
275
+ return self.cli_run()
276
+
277
+ #
278
+
279
+ async def async_cli_run(self) -> ta.Optional[int]:
280
+ if (fn := self.prepare_cli_run()) is None:
281
+ return 0
240
282
 
241
- def call_and_exit(self) -> ta.NoReturn:
242
- sys.exit(rc if isinstance(rc := self(), int) else 0)
283
+ return await fn()
omlish/asyncs/__init__.py CHANGED
@@ -1,35 +0,0 @@
1
- from .asyncs import ( # noqa
2
- SyncableIterable,
3
- async_list,
4
- sync_await,
5
- sync_list,
6
- syncable_iterable,
7
- )
8
-
9
- from .bridge import ( # noqa
10
- a_to_s,
11
- is_in_bridge,
12
- s_to_a,
13
- s_to_a_await,
14
- trivial_a_to_s,
15
- trivial_s_to_a,
16
- )
17
-
18
- from .flavors import ( # noqa
19
- ContextManagerAdapter,
20
- Flavor,
21
- adapt,
22
- adapt_context,
23
- from_anyio,
24
- from_anyio_context,
25
- from_asyncio,
26
- from_asyncio_context,
27
- from_trio,
28
- from_trio_context,
29
- get_flavor,
30
- mark_anyio,
31
- mark_asyncio,
32
- mark_flavor,
33
- mark_trio,
34
- with_adapter_loop,
35
- )
omlish/asyncs/all.py ADDED
@@ -0,0 +1,35 @@
1
+ from .asyncs import ( # noqa
2
+ SyncableIterable,
3
+ async_list,
4
+ sync_await,
5
+ sync_list,
6
+ syncable_iterable,
7
+ )
8
+
9
+ from .bridge import ( # noqa
10
+ a_to_s,
11
+ is_in_bridge,
12
+ s_to_a,
13
+ s_to_a_await,
14
+ trivial_a_to_s,
15
+ trivial_s_to_a,
16
+ )
17
+
18
+ from .flavors import ( # noqa
19
+ ContextManagerAdapter,
20
+ Flavor,
21
+ adapt,
22
+ adapt_context,
23
+ from_anyio,
24
+ from_anyio_context,
25
+ from_asyncio,
26
+ from_asyncio_context,
27
+ from_trio,
28
+ from_trio_context,
29
+ get_flavor,
30
+ mark_anyio,
31
+ mark_asyncio,
32
+ mark_flavor,
33
+ mark_trio,
34
+ with_adapter_loop,
35
+ )
File without changes
@@ -0,0 +1,7 @@
1
+ # ruff: noqa: I001
2
+ from .asyncio import ( # noqa
3
+ asyncio_once,
4
+ get_real_current_loop,
5
+ drain_tasks,
6
+ draining_asyncio_tasks,
7
+ )
@@ -0,0 +1,40 @@
1
+ # ruff: noqa: UP006 UP007
2
+ # @omlish-lite
3
+ import asyncio
4
+ import typing as ta
5
+
6
+
7
+ class AsyncioBytesChannelTransport(asyncio.Transport):
8
+ def __init__(self, reader: asyncio.StreamReader) -> None:
9
+ super().__init__()
10
+
11
+ self.reader = reader
12
+ self.closed: asyncio.Future = asyncio.Future()
13
+
14
+ # @ta.override
15
+ def write(self, data: bytes) -> None:
16
+ self.reader.feed_data(data)
17
+
18
+ # @ta.override
19
+ def close(self) -> None:
20
+ self.reader.feed_eof()
21
+ if not self.closed.done():
22
+ self.closed.set_result(True)
23
+
24
+ # @ta.override
25
+ def is_closing(self) -> bool:
26
+ return self.closed.done()
27
+
28
+
29
+ def asyncio_create_bytes_channel(
30
+ loop: ta.Any = None,
31
+ ) -> ta.Tuple[asyncio.StreamReader, asyncio.StreamWriter]:
32
+ if loop is None:
33
+ loop = asyncio.get_running_loop()
34
+
35
+ reader = asyncio.StreamReader()
36
+ protocol = asyncio.StreamReaderProtocol(reader)
37
+ transport = AsyncioBytesChannelTransport(reader)
38
+ writer = asyncio.StreamWriter(transport, protocol, reader, loop)
39
+
40
+ return reader, writer
@@ -1,15 +1,9 @@
1
1
  # ruff: noqa: UP006 UP007
2
- import asyncio.base_subprocess
3
- import asyncio.subprocess
2
+ # @omlish-lite
3
+ import asyncio
4
4
  import typing as ta
5
5
 
6
6
 
7
- AwaitableT = ta.TypeVar('AwaitableT', bound=ta.Awaitable)
8
-
9
-
10
- ##
11
-
12
-
13
7
  ASYNCIO_DEFAULT_BUFFER_LIMIT = 2 ** 16
14
8
 
15
9
 
@@ -49,15 +43,3 @@ async def asyncio_open_stream_writer(
49
43
  None,
50
44
  loop,
51
45
  )
52
-
53
-
54
- ##
55
-
56
-
57
- def asyncio_maybe_timeout(
58
- fut: AwaitableT,
59
- timeout: ta.Optional[float] = None,
60
- ) -> AwaitableT:
61
- if timeout is not None:
62
- fut = asyncio.wait_for(fut, timeout) # type: ignore
63
- return fut
@@ -0,0 +1,16 @@
1
+ # ruff: noqa: UP006 UP007
2
+ # @omlish-lite
3
+ import asyncio
4
+ import typing as ta
5
+
6
+
7
+ AwaitableT = ta.TypeVar('AwaitableT', bound=ta.Awaitable)
8
+
9
+
10
+ def asyncio_maybe_timeout(
11
+ fut: AwaitableT,
12
+ timeout: ta.Optional[float] = None,
13
+ ) -> AwaitableT:
14
+ if timeout is not None:
15
+ fut = asyncio.wait_for(fut, timeout) # type: ignore
16
+ return fut
omlish/bootstrap/sys.py CHANGED
@@ -23,13 +23,13 @@ if ta.TYPE_CHECKING:
23
23
  from .. import libc
24
24
  from .. import logs
25
25
  from ..formats import dotenv
26
- from ..lite import pidfile
26
+ from ..os import pidfile
27
27
 
28
28
  else:
29
29
  libc = lang.proxy_import('..libc', __package__)
30
30
  logs = lang.proxy_import('..logs', __package__)
31
31
  dotenv = lang.proxy_import('..formats.dotenv', __package__)
32
- pidfile = lang.proxy_import('..lite.pidfile', __package__)
32
+ pidfile = lang.proxy_import('..os.pidfile', __package__)
33
33
 
34
34
 
35
35
  ##
omlish/diag/procfs.py CHANGED
@@ -13,8 +13,8 @@ import typing as ta
13
13
 
14
14
  from .. import iterators as it
15
15
  from .. import lang
16
- from .. import os as oos
17
16
  from ..formats import json
17
+ from ..os.sizes import PAGE_SIZE
18
18
  from .procstats import ProcStats
19
19
 
20
20
 
@@ -239,8 +239,8 @@ def get_process_range_pagemaps(start: int, end: int, pid: PidLike = 'self') -> t
239
239
  """https://www.kernel.org/doc/Documentation/vm/pagemap.txt"""
240
240
 
241
241
  _check_linux()
242
- offset = (start // oos.PAGE_SIZE) * 8
243
- npages = ((end - start) // oos.PAGE_SIZE)
242
+ offset = (start // PAGE_SIZE) * 8
243
+ npages = ((end - start) // PAGE_SIZE)
244
244
  size = npages * 8
245
245
  with open(f'/proc/{pid}/pagemap', 'rb') as pagemap_file:
246
246
  pagemap_file.seek(offset)
@@ -251,7 +251,7 @@ def get_process_range_pagemaps(start: int, end: int, pid: PidLike = 'self') -> t
251
251
  for pagenum in range(npages):
252
252
  [packed] = _struct_unpack('Q', pagemap_buf[pagenum * 8:(pagenum + 1) * 8])
253
253
  yield {
254
- 'address': start + (pagenum * oos.PAGE_SIZE),
254
+ 'address': start + (pagenum * PAGE_SIZE),
255
255
  'pfn': (packed & ((1 << (54 + 1)) - 1)),
256
256
  'swap_type': (packed & ((1 << (4 + 1)) - 1)),
257
257
  'swap_offset': (packed & ((1 << (54 + 1)) - 1)) >> 5,
@@ -280,7 +280,7 @@ def _dump_cmd(args: ta.Any) -> None:
280
280
  sys.stdout.write('\n')
281
281
  for pm in get_process_range_pagemaps(m['address'], m['end_address'], args.pid):
282
282
  if pm['pte_soft_dirty']:
283
- dirty_total += oos.PAGE_SIZE
283
+ dirty_total += PAGE_SIZE
284
284
  sys.stdout.write(json.dumps({'page': tuple(pm[k] for k in PAGEMAP_KEYS)}))
285
285
  sys.stdout.write('\n')
286
286
  dct = {
@@ -326,11 +326,11 @@ def _cmp_cmd(args: ta.Any) -> None:
326
326
  r_pages += c_pages
327
327
  dct = {
328
328
  'l_pages': l_pages,
329
- 'l_bytes': l_pages * oos.PAGE_SIZE,
329
+ 'l_bytes': l_pages * PAGE_SIZE,
330
330
  'r_pages': r_pages,
331
- 'r_bytes': r_pages * oos.PAGE_SIZE,
331
+ 'r_bytes': r_pages * PAGE_SIZE,
332
332
  'c_pages': c_pages,
333
- 'c_bytes': c_pages * oos.PAGE_SIZE,
333
+ 'c_bytes': c_pages * PAGE_SIZE,
334
334
  }
335
335
  sys.stdout.write(json.dumps(dct))
336
336
  sys.stdout.write('\n')
omlish/inject/managed.py CHANGED
@@ -14,9 +14,9 @@ from .injector import create_injector
14
14
 
15
15
 
16
16
  if ta.TYPE_CHECKING:
17
- from .. import asyncs as _asyncs
17
+ from ..asyncs import all as _asyncs
18
18
  else:
19
- _asyncs = lang.proxy_import('..asyncs', __package__)
19
+ _asyncs = lang.proxy_import('..asyncs.all', __package__)
20
20
 
21
21
 
22
22
  T = ta.TypeVar('T')
@@ -8,12 +8,12 @@ import subprocess
8
8
  import sys
9
9
  import typing as ta
10
10
 
11
+ from ...asyncs.asyncio.timeouts import asyncio_maybe_timeout
11
12
  from ..check import check
12
13
  from ..logs import log
13
14
  from ..subprocesses import DEFAULT_SUBPROCESS_TRY_EXCEPTIONS
14
15
  from ..subprocesses import prepare_subprocess_invocation
15
16
  from ..subprocesses import subprocess_common_context
16
- from .asyncio import asyncio_maybe_timeout
17
17
 
18
18
 
19
19
  T = ta.TypeVar('T')
@@ -177,22 +177,25 @@ async def asyncio_subprocess_communicate(
177
177
  return await AsyncioProcessCommunicator(proc).communicate(input, timeout) # noqa
178
178
 
179
179
 
180
- ##
181
-
182
-
183
- async def _asyncio_subprocess_check_run(
180
+ async def asyncio_subprocess_run(
184
181
  *args: str,
185
182
  input: ta.Any = None, # noqa
186
183
  timeout: ta.Optional[float] = None,
184
+ check: bool = False, # noqa
185
+ capture_output: ta.Optional[bool] = None,
187
186
  **kwargs: ta.Any,
188
187
  ) -> ta.Tuple[ta.Optional[bytes], ta.Optional[bytes]]:
188
+ if capture_output:
189
+ kwargs.setdefault('stdout', subprocess.PIPE)
190
+ kwargs.setdefault('stderr', subprocess.PIPE)
191
+
189
192
  args, kwargs = prepare_subprocess_invocation(*args, **kwargs)
190
193
 
191
194
  proc: asyncio.subprocess.Process
192
195
  async with asyncio_subprocess_popen(*args, **kwargs) as proc:
193
196
  stdout, stderr = await asyncio_subprocess_communicate(proc, input, timeout)
194
197
 
195
- if proc.returncode:
198
+ if check and proc.returncode:
196
199
  raise subprocess.CalledProcessError(
197
200
  proc.returncode,
198
201
  args,
@@ -203,6 +206,9 @@ async def _asyncio_subprocess_check_run(
203
206
  return stdout, stderr
204
207
 
205
208
 
209
+ ##
210
+
211
+
206
212
  async def asyncio_subprocess_check_call(
207
213
  *args: str,
208
214
  stdout: ta.Any = sys.stderr,
@@ -210,11 +216,12 @@ async def asyncio_subprocess_check_call(
210
216
  timeout: ta.Optional[float] = None,
211
217
  **kwargs: ta.Any,
212
218
  ) -> None:
213
- _, _ = await _asyncio_subprocess_check_run(
219
+ _, _ = await asyncio_subprocess_run(
214
220
  *args,
215
221
  stdout=stdout,
216
222
  input=input,
217
223
  timeout=timeout,
224
+ check=True,
218
225
  **kwargs,
219
226
  )
220
227
 
@@ -225,11 +232,12 @@ async def asyncio_subprocess_check_output(
225
232
  timeout: ta.Optional[float] = None,
226
233
  **kwargs: ta.Any,
227
234
  ) -> bytes:
228
- stdout, stderr = await _asyncio_subprocess_check_run(
235
+ stdout, stderr = await asyncio_subprocess_run(
229
236
  *args,
230
237
  stdout=asyncio.subprocess.PIPE,
231
238
  input=input,
232
239
  timeout=timeout,
240
+ check=True,
233
241
  **kwargs,
234
242
  )
235
243
 
@@ -13,7 +13,7 @@ from .runtime import is_debugger_attached
13
13
 
14
14
 
15
15
  T = ta.TypeVar('T')
16
- SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull']
16
+ SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull'] # ta.TypeAlias
17
17
 
18
18
 
19
19
  ##
omlish/os/__init__.py ADDED
File without changes
@@ -1,3 +1,4 @@
1
+ # @omlish-lite
1
2
  import ctypes as ct
2
3
  import sys
3
4
 
@@ -1,19 +1,10 @@
1
1
  import contextlib
2
2
  import os
3
- import resource
4
3
  import shutil
5
4
  import tempfile
6
5
  import typing as ta
7
6
 
8
7
 
9
- PAGE_SIZE = resource.getpagesize()
10
-
11
-
12
- def round_to_page_size(sz: int) -> int:
13
- sz += PAGE_SIZE - 1
14
- return sz - (sz % PAGE_SIZE)
15
-
16
-
17
8
  @contextlib.contextmanager
18
9
  def tmp_dir(
19
10
  root_dir: str | None = None,
@@ -1,4 +1,5 @@
1
1
  # ruff: noqa: UP007 UP012
2
+ # @omlish-lite
2
3
  import ctypes as ct
3
4
  import logging
4
5
  import sys
@@ -6,7 +7,7 @@ import syslog
6
7
  import threading
7
8
  import typing as ta
8
9
 
9
- from .cached import cached_nullary
10
+ from ..lite.cached import cached_nullary
10
11
 
11
12
 
12
13
  ##
@@ -1,4 +1,5 @@
1
1
  # ruff: noqa: UP007
2
+ # @omlish-lite
2
3
  import fcntl
3
4
  import os
4
5
  import signal
omlish/os/sizes.py ADDED
@@ -0,0 +1,9 @@
1
+ import resource
2
+
3
+
4
+ PAGE_SIZE = resource.getpagesize()
5
+
6
+
7
+ def round_to_page_size(sz: int) -> int:
8
+ sz += PAGE_SIZE - 1
9
+ return sz - (sz % PAGE_SIZE)
@@ -9,7 +9,7 @@ import typing as ta
9
9
  import sqlalchemy as sa
10
10
  import sqlalchemy.ext.asyncio as saa
11
11
 
12
- from ... import asyncs as au
12
+ from ...asyncs import all as au
13
13
 
14
14
 
15
15
  T = ta.TypeVar('T')
@@ -7,9 +7,9 @@ from .plugins.managermarks import ManagerMark # noqa
7
7
 
8
8
 
9
9
  if ta.TYPE_CHECKING:
10
- from ...asyncs import asyncio as aiu
10
+ from ...asyncs.asyncio import all as aiu
11
11
  else:
12
- aiu = lang.proxy_import('...asyncs.asyncio', __package__)
12
+ aiu = lang.proxy_import('...asyncs.asyncio.all', __package__)
13
13
 
14
14
 
15
15
  class drain_asyncio(ManagerMark): # noqa
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omlish
3
- Version: 0.0.0.dev151
3
+ Version: 0.0.0.dev153
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=RX24SRc6DCEg77PUVnaXOKCWa5TF_c9RQJdGIf7gl9c,1135
2
- omlish/__about__.py,sha256=D7fRdocKBDAO3XGagNp2LA5SC8TzrHHiKg6TnIulAVM,3409
2
+ omlish/__about__.py,sha256=b3YvnZv7CD-eAnC8X8P0BTKSk3UmrhaMttytZs3utcs,3409
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=ubu7lHwss5V4UznbejAI0qXhXahrU01MysuHOZI9C4U,8116
5
5
  omlish/cached.py,sha256=UI-XTFBwA6YXWJJJeBn-WkwBkfzDjLBBaZf4nIJA9y0,510
@@ -10,7 +10,6 @@ omlish/dynamic.py,sha256=35C_cCX_Vq2HrHzGk5T-zbrMvmUdiIiwDzDNixczoDo,6541
10
10
  omlish/iterators.py,sha256=GGLC7RIT86uXMjhIIIqnff_Iu5SI_b9rXYywYGFyzmo,7292
11
11
  omlish/libc.py,sha256=8r7Ejyhttk9ruCfBkxNTrlzir5WPbDE2vmY7VPlceMA,15362
12
12
  omlish/multiprocessing.py,sha256=QZT4C7I-uThCAjaEY3xgUYb-5GagUlnE4etN01LDyU4,5186
13
- omlish/os.py,sha256=5nJ-a9JKSMoaZVZ1eOa5BAbfL7o7CF7ue_PyJwufnwY,1460
14
13
  omlish/runmodule.py,sha256=PWvuAaJ9wQQn6bx9ftEL3_d04DyotNn8dR_twm2pgw0,700
15
14
  omlish/sync.py,sha256=QJ79kxmIqDP9SeHDoZAf--DpFIhDQe1jACy8H4N0yZI,2928
16
15
  omlish/term.py,sha256=BXJSE9gfM461bh4z_gysx0oavZSafqcQs5ayZK-kTUo,9284
@@ -76,15 +75,21 @@ omlish/antlr/_runtime/xpath/XPathLexer.py,sha256=xFtdr4ZXMZxb2dnB_ggWyhvlQiC7RXQ
76
75
  omlish/antlr/_runtime/xpath/__init__.py,sha256=lMd_BbXYdlDhZQN_q0TKN978XW5G0pq618F0NaLkpFE,71
77
76
  omlish/argparse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
77
  omlish/argparse/all.py,sha256=EfUSf27vFWqa4Q93AycU5YRsrHt-Nx3pU3uNVapb-EE,1054
79
- omlish/argparse/cli.py,sha256=cnF_WfAqt_0BIEyF4Xxh4yVkaCc5Mi83GfwIKwwytuM,7436
80
- omlish/asyncs/__init__.py,sha256=uUz9ziKh4_QrgmdhKFMgq6j7mFbiZd3LiogguDCQsGI,587
78
+ omlish/argparse/cli.py,sha256=RrFql1bS1Lw3GA1ooLCJDQX4bK_Ci-dDqD5nEkVgHGI,8072
79
+ omlish/asyncs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
+ omlish/asyncs/all.py,sha256=uUz9ziKh4_QrgmdhKFMgq6j7mFbiZd3LiogguDCQsGI,587
81
81
  omlish/asyncs/anyio.py,sha256=gfpx-D8QGmUfhnQxHEaHXcAP8zSMQjcGw4COFTGNnHI,8021
82
- omlish/asyncs/asyncio.py,sha256=JfM59QgB3asgEbrps0zoVbNjWD4kL2XdsEkRMEIoFos,971
83
82
  omlish/asyncs/asyncs.py,sha256=Tf7ZodTGepkM7HAuFcDNh9lLzzrMw6rELWvopGmFkh4,2035
84
83
  omlish/asyncs/bridge.py,sha256=GJOjXVwZJvpq2q9rCwRI2u7Tg-KLUx-SY92b873-M4c,9738
85
84
  omlish/asyncs/flavors.py,sha256=1mNxGNRVmjUHzA13K5ht8vdJv4CLEmzYTQ6BZXr1520,4866
86
85
  omlish/asyncs/trio.py,sha256=fmZ5b_lKdVV8NQ3euCUutWgnkqTFzSnOjvJSA_jvmrE,367
87
86
  omlish/asyncs/trio_asyncio.py,sha256=oqdOHy0slj9PjVxaDf3gJkq9AAgg7wYZbB469jOftVw,1327
87
+ omlish/asyncs/asyncio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
+ omlish/asyncs/asyncio/all.py,sha256=cyfe1tOXxQYmgfyF9X1dwx0LPQ0Gsub3tFFZGjWGMr8,142
89
+ omlish/asyncs/asyncio/asyncio.py,sha256=JfM59QgB3asgEbrps0zoVbNjWD4kL2XdsEkRMEIoFos,971
90
+ omlish/asyncs/asyncio/channels.py,sha256=ZbmsEmdK1fV96liHdcVpRqA2dAMkXJt4Q3rFAg3YOIw,1074
91
+ omlish/asyncs/asyncio/streams.py,sha256=Uc9PCWSfBqrK2kdVtfjjQU1eaYTWYmZm8QISDj2xiuw,1004
92
+ omlish/asyncs/asyncio/timeouts.py,sha256=Rj5OU9BIAPcVZZKp74z7SzUXF5xokh4dgsWkUqOy1aE,355
88
93
  omlish/bootstrap/__init__.py,sha256=-Rtsg7uPQNhh1dIT9nqrz96XlqizwoLnWf-FwOEstJI,730
89
94
  omlish/bootstrap/__main__.py,sha256=4jCwsaogp0FrJjJZ85hzF4-WqluPeheHbfeoKynKvNs,194
90
95
  omlish/bootstrap/base.py,sha256=d8hqn4hp1XMMi5PgcJBQXPKmW47epu8CxBlqDZiRZb4,1073
@@ -92,7 +97,7 @@ omlish/bootstrap/diag.py,sha256=iemH0nQEHEDzyZztvd_ygGGVpRpgn5UG6naxeQTvXp0,5347
92
97
  omlish/bootstrap/harness.py,sha256=VW8YP-yENGyXIuJ8GL_xintArF13nafwpz-iAghPt34,1967
93
98
  omlish/bootstrap/main.py,sha256=yZhOHDDlj4xB5a89dRdT8z58FsqqnpoBg1-tvY2CJe4,5903
94
99
  omlish/bootstrap/marshal.py,sha256=ZxdAeMNd2qXRZ1HUK89HmEhz8tqlS9OduW34QBscKw0,516
95
- omlish/bootstrap/sys.py,sha256=iLHUNIuIPv-k-Mc6aHj5sSET78olCVt7t0HquFDO4iQ,8762
100
+ omlish/bootstrap/sys.py,sha256=S6HgjfCKYNuC_iW6gIJNVp8-eJ_wm0JTBMyQRZLE6eQ,8758
96
101
  omlish/collections/__init__.py,sha256=zeUvcAz073ekko37QKya6sElTMfKTuF1bKrdbMtaRpI,2142
97
102
  omlish/collections/abc.py,sha256=sP7BpTVhx6s6C59mTFeosBi4rHOWC6tbFBYbxdZmvh0,2365
98
103
  omlish/collections/coerce.py,sha256=g68ROb_-5HgH-vI8612mU2S0FZ8-wp2ZHK5_Zy_kVC0,7037
@@ -151,7 +156,7 @@ omlish/dataclasses/impl/utils.py,sha256=aER2iL3UAtgS1BdLuEvTr9Tr2wC28wk1kiOeO-jI
151
156
  omlish/diag/__init__.py,sha256=4S8v0myJM4Zld6_FV6cPe_nSv0aJb6kXftEit0HkiGE,1141
152
157
  omlish/diag/asts.py,sha256=BveUUNUcaAm4Hg55f4ZxGSI313E4L8cCZ5XjHpEkKVI,3325
153
158
  omlish/diag/debug.py,sha256=ClED7kKXeVMyKrjGIxcq14kXk9kvUJfytBQwK9y7c4Q,1637
154
- omlish/diag/procfs.py,sha256=vBovaMvAUKdl7FbtFq3TNsSmdhs8DaYfhoEsKeWYta8,9704
159
+ omlish/diag/procfs.py,sha256=KaGTAA2Gj8eEEp7MjClRe4aimwzd-HDABThFzvq2cBQ,9684
155
160
  omlish/diag/procstats.py,sha256=UkqxREqfd-38xPYZ9T1SIJISz5ARQCEhTtOZrxtm2dE,777
156
161
  omlish/diag/ps.py,sha256=1JWxZen3fVG-20R6ZZ8BtO_gpzw_5bhHZiKdoHkgxoU,1004
157
162
  omlish/diag/pycharm.py,sha256=7-r_F-whXt8v-0dehxAX-MeMFPM3iZXX9IfeL0GfUtk,4643
@@ -246,7 +251,7 @@ omlish/inject/injector.py,sha256=CoCUeMm1Oot4sG4Ti1sKCWrhlvtJ5QAeAI22AFWu2RQ,106
246
251
  omlish/inject/inspect.py,sha256=tw49r1RJVHrEHmT8WWA3_Bl9Z0L3lEGRqlLhbM5OmAM,592
247
252
  omlish/inject/keys.py,sha256=BczsGcNvoziQYggGKX3_XpRZQ3b0F_pYWSDLBg5lRvE,654
248
253
  omlish/inject/listeners.py,sha256=AIWUs4OTUPeURU1tS2CXeEbJwC1bZiuya9K6I2ElMns,581
249
- omlish/inject/managed.py,sha256=Ls54Ah5KDrLHYWmso64xipvCLWPcgl1sUOn2n1tuWag,2107
254
+ omlish/inject/managed.py,sha256=ASHaY57v9POUOpwgCiinTbE14U28ysl3D6RcFkLfcOQ,2114
250
255
  omlish/inject/multis.py,sha256=a3DparPZjLdkAYFuEFTI6kM3BhNpJbtjeAMRdbeJx0c,3363
251
256
  omlish/inject/origins.py,sha256=OVQkiuRxx6ZtE8ZliufdndtFexcfpj-wZSDkUeGUCYM,534
252
257
  omlish/inject/overrides.py,sha256=hrm243slCw_DDRbn3dK5QK1jfHezVokG-WYO2JaQOV8,535
@@ -331,14 +336,11 @@ omlish/lite/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
331
336
  omlish/lite/cached.py,sha256=hBW77-F7ZLtFqbLwVrlqaJ4-iFHMQleMWZXaZN1IubA,1308
332
337
  omlish/lite/check.py,sha256=tAKB99X_oHG3JADUgZXMdPzgN8aNF9UBuJv4WeSgM_A,12877
333
338
  omlish/lite/contextmanagers.py,sha256=4tKuBYyxn-aI31QowIuClHgpML8JsdzCW3j5ms_-uuY,1418
334
- omlish/lite/deathsig.py,sha256=Etz04WX6R2PXQ-BgqJyVJ0C5Pqym6Ds6PAG7p1cqr5o,626
335
339
  omlish/lite/inject.py,sha256=729Qi0TLbQgBtkvx97q1EUMe73VFYA1hu4woXkOTcwM,23572
336
- omlish/lite/journald.py,sha256=f5Y2Q6-6O3iK_7MoGiwZwoQEOcP7LfkxxQNUR9tMjJM,3882
337
340
  omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
338
341
  omlish/lite/logs.py,sha256=1pcGu0ekhVCcLUckLSP16VccnAoprjtl5Vkdfm7y1Wg,6184
339
342
  omlish/lite/marshal.py,sha256=6dCv_H4MF0BgzQ1XfIn30eE5jr4S96IfDi7anbBFl2c,13485
340
343
  omlish/lite/maybes.py,sha256=7OlHJ8Q2r4wQ-aRbZSlJY7x0e8gDvufFdlohGEIJ3P4,833
341
- omlish/lite/pidfile.py,sha256=PRSDOAXmNkNwxh-Vwif0Nrs8RAmWroiNhLKIbdjwzBc,1723
342
344
  omlish/lite/pycharm.py,sha256=pUOJevrPClSqTCEOkQBO11LKX2003tfDcp18a03QFrc,1163
343
345
  omlish/lite/reflect.py,sha256=ad_ya_zZJOQB8HoNjs9yc66R54zgflwJVPJqiBXMzqA,1681
344
346
  omlish/lite/resources.py,sha256=YNSmX1Ohck1aoWRs55a-o5ChVbFJIQhtbqE-XwF55Oc,326
@@ -347,11 +349,10 @@ omlish/lite/secrets.py,sha256=3Mz3V2jf__XU9qNHcH56sBSw95L3U2UPL24bjvobG0c,816
347
349
  omlish/lite/socket.py,sha256=7OYgkXTcQv0wq7TQuLnl9y6dJA1ZT6Vbc1JH59QlxgY,1792
348
350
  omlish/lite/socketserver.py,sha256=doTXIctu_6c8XneFtzPFVG_Wq6xVmA3p9ymut8IvBoU,1586
349
351
  omlish/lite/strings.py,sha256=QURcE4-1pKVW8eT_5VCJpXaHDWR2dW2pYOChTJnZDiQ,1504
350
- omlish/lite/subprocesses.py,sha256=RTs8HJ1Lz8YOZTHw12Ja8KW7Eq4oyDFJZDiG0PSUBKY,4918
352
+ omlish/lite/subprocesses.py,sha256=iN-HX44g9uxkZ7HII2Upvkfjp7YK6qQuhPrBqM4Hnp0,4934
351
353
  omlish/lite/typing.py,sha256=U3-JaEnkDSYxK4tsu_MzUn3RP6qALBe5FXQXpD-licE,1090
352
354
  omlish/lite/asyncio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
353
- omlish/lite/asyncio/asyncio.py,sha256=tsqQSLl5rG4GZHPYOBqI7V2yuw45ZVuGZEHe-J4QEhE,1320
354
- omlish/lite/asyncio/subprocesses.py,sha256=uav2ZD70HQKGhRvFgDcptW_HFYwA_x0AKviCBwL0K_0,8163
355
+ omlish/lite/asyncio/subprocesses.py,sha256=FB9PbS17MCE2fvgbSUb30KOg8kiJe37DNioD51T8HOk,8427
355
356
  omlish/logs/__init__.py,sha256=FbOyAW-lGH8gyBlSVArwljdYAU6RnwZLI5LwAfuNnrk,438
356
357
  omlish/logs/abc.py,sha256=ho4ABKYMKX-V7g4sp1BByuOLzslYzLlQ0MESmjEpT-o,8005
357
358
  omlish/logs/configs.py,sha256=EE0jlNaXJbGnM7V-y4xS5VwyTBSTzFzc0BYaVjg0JmA,1283
@@ -396,6 +397,12 @@ omlish/math/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
396
397
  omlish/math/bits.py,sha256=yip1l8agOYzT7bFyMGc0RR3XlnGCfHMpjw_SECLLh1I,3477
397
398
  omlish/math/floats.py,sha256=UimhOT7KRl8LXTzOI5cQWoX_9h6WNWe_3vcOuO7-h_8,327
398
399
  omlish/math/stats.py,sha256=MegzKVsmv2kra4jDWLOUgV0X7Ee2Tbl5u6ql1v4-dEY,10053
400
+ omlish/os/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
401
+ omlish/os/deathsig.py,sha256=hk9Yq2kyDdI-cI7OQH7mOfpRbOKzY_TfPKEqgrjVYbA,641
402
+ omlish/os/files.py,sha256=1tNy1z5I_CgYKA5c6lOfsXc-hknP4tQDbSShdz8HArw,1308
403
+ omlish/os/journald.py,sha256=2nI8Res1poXkbLc31--MPUlzYMESnCcPUkIxDOCjZW0,3903
404
+ omlish/os/pidfile.py,sha256=S4Nbe00oSxckY0qCC9AeTEZe7NSw4eJudnQX7wCXzks,1738
405
+ omlish/os/sizes.py,sha256=ohkALLvqSqBX4iR-7DMKJ4pfOCRdZXV8htH4QywUNM0,152
399
406
  omlish/reflect/__init__.py,sha256=4-EuCSX1qpEWfScCFzAJv_XghHFu4cXxpxKeBKrosQ4,720
400
407
  omlish/reflect/inspect.py,sha256=veJ424-9oZrqyvhVpvxOi7hcKW-PDBkdYL2yjrFlk4o,495
401
408
  omlish/reflect/ops.py,sha256=RJ6jzrM4ieFsXzWyNXWV43O_WgzEaUvlHSc5N2ezW2A,2044
@@ -457,7 +464,7 @@ omlish/sql/dbs.py,sha256=lpdFmm2vTwLoBiVYGj9yPsVcTEYYNCxlYZZpjfChzkY,1870
457
464
  omlish/sql/params.py,sha256=Z4VPet6GhNqD1T_MXSWSHkdy3cpUEhST-OplC4B_fYI,4433
458
465
  omlish/sql/qualifiedname.py,sha256=rlW3gVmyucJbqwcxj_7BfK4X2HoXrMroZT2H45zPgJQ,2264
459
466
  omlish/sql/alchemy/__init__.py,sha256=1ruDMiviH5fjevn2xVki-QspcE9O3VPy4hxOqpHjI2s,224
460
- omlish/sql/alchemy/asyncs.py,sha256=C1bIzz9m2Qbgl4qYGQt_FRQg4BKRcxUqMsVg9RtnTPg,3689
467
+ omlish/sql/alchemy/asyncs.py,sha256=MwZwWIaZsUCQLcTA8mdHUPZmR-pXEVSAsvd15FCm3W4,3692
461
468
  omlish/sql/alchemy/duckdb.py,sha256=kr7pIhiBLNAuZrcigHDtFg9zHkVcrRW3LfryO9VJ4mk,3749
462
469
  omlish/sql/alchemy/exprs.py,sha256=gO4Fj4xEY-PuDgV-N8hBMy55glZz7O-4H7v1LWabfZY,323
463
470
  omlish/sql/alchemy/secrets.py,sha256=EMfy4EfTbEvrlv_41oOhn8qsoF-eTkY7HciPenIE6rI,178
@@ -489,7 +496,7 @@ omlish/testing/__init__.py,sha256=M_BQrcCHkoL-ZvE-UpQ8XxXNYRRawhjUz4rCJnAqM2A,15
489
496
  omlish/testing/testing.py,sha256=TT2wwSzPZ_KhIvKxpM1qc1yHKD-LHDNgGrcr_h8vs7c,2895
490
497
  omlish/testing/pytest/__init__.py,sha256=B2nyJrjIoNcEopbg0IZ5UUDs4OHmQ8qqElFJfGcDdas,257
491
498
  omlish/testing/pytest/helpers.py,sha256=TJpD60mBtLi9FtxX4TThfuXvg5FIRPSiZk1aeRwe-D4,197
492
- omlish/testing/pytest/marks.py,sha256=ExuwitbMr1txMbaAcWZ652pYa30M-i3wVacnjqschTs,424
499
+ omlish/testing/pytest/marks.py,sha256=4-3WgunN_fcmhkmQ6mtX_AFo5QRDwflNSH7NoyoXui4,432
493
500
  omlish/testing/pytest/skip.py,sha256=NxTkAQiS3HKZR3sfFdxOR2LCFwtCveY6Ap-qtexiZbw,839
494
501
  omlish/testing/pytest/inject/__init__.py,sha256=pdRKv1HcDmJ_yArKJbYITPXXZthRSGgBJWqITr0Er38,117
495
502
  omlish/testing/pytest/inject/harness.py,sha256=v4DaKJ0KL8oQjzIMK43Gh8GHP4hiI6-lY37O9lyOHRk,5724
@@ -512,9 +519,9 @@ omlish/text/glyphsplit.py,sha256=Ug-dPRO7x-OrNNr8g1y6DotSZ2KH0S-VcOmUobwa4B0,329
512
519
  omlish/text/indent.py,sha256=6Jj6TFY9unaPa4xPzrnZemJ-fHsV53IamP93XGjSUHs,1274
513
520
  omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
514
521
  omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
515
- omlish-0.0.0.dev151.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
516
- omlish-0.0.0.dev151.dist-info/METADATA,sha256=0_iQYyCyZ0t_LBY1iVoaAE45eNRW7Q-Q8VojC9ObbmA,4264
517
- omlish-0.0.0.dev151.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
518
- omlish-0.0.0.dev151.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
519
- omlish-0.0.0.dev151.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
520
- omlish-0.0.0.dev151.dist-info/RECORD,,
522
+ omlish-0.0.0.dev153.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
523
+ omlish-0.0.0.dev153.dist-info/METADATA,sha256=NANx-xsYundThAIFYybGp0wnUqq1fd7AhbGDyQ4CJxQ,4264
524
+ omlish-0.0.0.dev153.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
525
+ omlish-0.0.0.dev153.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
526
+ omlish-0.0.0.dev153.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
527
+ omlish-0.0.0.dev153.dist-info/RECORD,,
File without changes