omlish 0.0.0.dev216__py3-none-any.whl → 0.0.0.dev218__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 +2 -2
- omlish/asyncs/asyncio/all.py +4 -3
- omlish/dataclasses/__init__.py +6 -2
- omlish/dataclasses/utils.py +0 -12
- omlish/docker/oci/__init__.py +0 -0
- omlish/docker/oci/data.py +71 -0
- omlish/docker/oci/media.py +124 -0
- omlish/docker/portrelay.py +49 -0
- omlish/formats/json5/Json5.g4 +0 -3
- omlish/http/coro/server.py +45 -25
- omlish/http/handlers.py +11 -1
- omlish/iterators/tools.py +1 -0
- omlish/lang/imports.py +16 -8
- omlish/lite/dataclasses.py +3 -1
- omlish/logs/all.py +13 -0
- omlish/logs/callers.py +45 -0
- omlish/logs/protocol.py +176 -0
- omlish/marshal/dataclasses.py +26 -0
- omlish/sockets/addresses.py +13 -4
- omlish/sockets/bind.py +332 -0
- omlish/sockets/handlers.py +2 -20
- omlish/sockets/io.py +69 -0
- omlish/sockets/server/__init__.py +0 -0
- omlish/sockets/server/handlers.py +99 -0
- omlish/sockets/server/server.py +144 -0
- omlish/sockets/server/threading.py +123 -0
- omlish/subprocesses.py +65 -3
- {omlish-0.0.0.dev216.dist-info → omlish-0.0.0.dev218.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev216.dist-info → omlish-0.0.0.dev218.dist-info}/RECORD +33 -22
- omlish/sockets/server.py +0 -66
- {omlish-0.0.0.dev216.dist-info → omlish-0.0.0.dev218.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev216.dist-info → omlish-0.0.0.dev218.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev216.dist-info → omlish-0.0.0.dev218.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev216.dist-info → omlish-0.0.0.dev218.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
# @omlish-lite
|
2
|
+
# ruff: noqa: UP006 UP007
|
3
|
+
import dataclasses as dc
|
4
|
+
import socket
|
5
|
+
import typing as ta
|
6
|
+
|
7
|
+
from ..addresses import SocketAndAddress
|
8
|
+
from ..handlers import SocketHandler
|
9
|
+
from ..io import SocketIoPair
|
10
|
+
from ..io import close_socket_immediately
|
11
|
+
|
12
|
+
|
13
|
+
SocketServerHandler = ta.Callable[[SocketAndAddress], None] # ta.TypeAlias
|
14
|
+
|
15
|
+
|
16
|
+
##
|
17
|
+
|
18
|
+
|
19
|
+
@dc.dataclass(frozen=True)
|
20
|
+
class StandardSocketServerHandler:
|
21
|
+
handler: SocketServerHandler
|
22
|
+
|
23
|
+
timeout: ta.Optional[float] = None
|
24
|
+
|
25
|
+
# http://bugs.python.org/issue6192
|
26
|
+
# TODO: https://eklitzke.org/the-caveats-of-tcp-nodelay
|
27
|
+
disable_nagle_algorithm: bool = False
|
28
|
+
|
29
|
+
no_close: bool = False
|
30
|
+
|
31
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
32
|
+
try:
|
33
|
+
if self.timeout is not None:
|
34
|
+
conn.socket.settimeout(self.timeout)
|
35
|
+
|
36
|
+
if self.disable_nagle_algorithm:
|
37
|
+
conn.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
|
38
|
+
|
39
|
+
self.handler(conn)
|
40
|
+
|
41
|
+
finally:
|
42
|
+
close_socket_immediately(conn.socket)
|
43
|
+
|
44
|
+
|
45
|
+
#
|
46
|
+
|
47
|
+
|
48
|
+
@dc.dataclass(frozen=True)
|
49
|
+
class CallbackWrappedSocketServerHandler:
|
50
|
+
handler: SocketServerHandler
|
51
|
+
|
52
|
+
before_handle: ta.Optional[SocketServerHandler] = None
|
53
|
+
after_handle: ta.Optional[SocketServerHandler] = None
|
54
|
+
|
55
|
+
# Return True if suppress like __exit__
|
56
|
+
on_error: ta.Optional[ta.Callable[[SocketAndAddress, Exception], bool]] = None
|
57
|
+
|
58
|
+
finally_: ta.Optional[SocketServerHandler] = None
|
59
|
+
|
60
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
61
|
+
try:
|
62
|
+
if (before_handle := self.before_handle) is not None:
|
63
|
+
before_handle(conn)
|
64
|
+
|
65
|
+
self.handler(conn)
|
66
|
+
|
67
|
+
except Exception as e:
|
68
|
+
if (on_error := self.on_error) is not None and on_error(conn, e):
|
69
|
+
pass
|
70
|
+
else:
|
71
|
+
raise
|
72
|
+
|
73
|
+
else:
|
74
|
+
if (after_handle := self.after_handle) is not None:
|
75
|
+
after_handle(conn)
|
76
|
+
|
77
|
+
finally:
|
78
|
+
if (finally_ := self.finally_) is not None:
|
79
|
+
finally_(conn)
|
80
|
+
|
81
|
+
|
82
|
+
#
|
83
|
+
|
84
|
+
|
85
|
+
@dc.dataclass(frozen=True)
|
86
|
+
class SocketHandlerSocketServerHandler:
|
87
|
+
handler: SocketHandler
|
88
|
+
|
89
|
+
r_buf_size: int = -1
|
90
|
+
w_buf_size: int = 0
|
91
|
+
|
92
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
93
|
+
fp = SocketIoPair.from_socket(
|
94
|
+
conn.socket,
|
95
|
+
r_buf_size=self.r_buf_size,
|
96
|
+
w_buf_size=self.w_buf_size,
|
97
|
+
)
|
98
|
+
|
99
|
+
self.handler(conn.address, fp)
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# @omlish-lite
|
2
|
+
# ruff: noqa: UP006 UP007
|
3
|
+
import abc
|
4
|
+
import contextlib
|
5
|
+
import selectors
|
6
|
+
import threading
|
7
|
+
import typing as ta
|
8
|
+
|
9
|
+
from ..bind import SocketBinder
|
10
|
+
from .handlers import SocketServerHandler
|
11
|
+
|
12
|
+
|
13
|
+
##
|
14
|
+
|
15
|
+
|
16
|
+
class SocketServer(abc.ABC):
|
17
|
+
def __init__(
|
18
|
+
self,
|
19
|
+
binder: SocketBinder,
|
20
|
+
handler: SocketServerHandler,
|
21
|
+
*,
|
22
|
+
on_error: ta.Optional[ta.Callable[[BaseException], None]] = None,
|
23
|
+
poll_interval: float = .5,
|
24
|
+
shutdown_timeout: ta.Optional[float] = None,
|
25
|
+
) -> None:
|
26
|
+
super().__init__()
|
27
|
+
|
28
|
+
self._binder = binder
|
29
|
+
self._handler = handler
|
30
|
+
self._on_error = on_error
|
31
|
+
self._poll_interval = poll_interval
|
32
|
+
self._shutdown_timeout = shutdown_timeout
|
33
|
+
|
34
|
+
self._lock = threading.RLock()
|
35
|
+
self._is_shutdown = threading.Event()
|
36
|
+
self._should_shutdown = False
|
37
|
+
|
38
|
+
@property
|
39
|
+
def binder(self) -> SocketBinder:
|
40
|
+
return self._binder
|
41
|
+
|
42
|
+
@property
|
43
|
+
def handler(self) -> SocketServerHandler:
|
44
|
+
return self._handler
|
45
|
+
|
46
|
+
#
|
47
|
+
|
48
|
+
class SelectorProtocol(ta.Protocol):
|
49
|
+
def register(self, *args, **kwargs) -> None:
|
50
|
+
raise NotImplementedError
|
51
|
+
|
52
|
+
def select(self, *args, **kwargs) -> bool:
|
53
|
+
raise NotImplementedError
|
54
|
+
|
55
|
+
Selector: ta.ClassVar[ta.Any]
|
56
|
+
if hasattr(selectors, 'PollSelector'):
|
57
|
+
Selector = selectors.PollSelector
|
58
|
+
else:
|
59
|
+
Selector = selectors.SelectSelector
|
60
|
+
|
61
|
+
#
|
62
|
+
|
63
|
+
@contextlib.contextmanager
|
64
|
+
def _listen_context(self) -> ta.Iterator[SelectorProtocol]:
|
65
|
+
with contextlib.ExitStack() as es:
|
66
|
+
es.enter_context(self._lock)
|
67
|
+
es.enter_context(self._binder)
|
68
|
+
|
69
|
+
self._binder.listen()
|
70
|
+
|
71
|
+
self._is_shutdown.clear()
|
72
|
+
try:
|
73
|
+
# XXX: Consider using another file descriptor or connecting to the socket to wake this up instead of
|
74
|
+
# polling. Polling reduces our responsiveness to a shutdown request and wastes cpu at all other times.
|
75
|
+
with self.Selector() as selector:
|
76
|
+
selector.register(self._binder.fileno(), selectors.EVENT_READ)
|
77
|
+
|
78
|
+
yield selector
|
79
|
+
|
80
|
+
finally:
|
81
|
+
self._is_shutdown.set()
|
82
|
+
|
83
|
+
@contextlib.contextmanager
|
84
|
+
def loop_context(self, poll_interval: ta.Optional[float] = None) -> ta.Iterator[ta.Iterator[bool]]:
|
85
|
+
if poll_interval is None:
|
86
|
+
poll_interval = self._poll_interval
|
87
|
+
|
88
|
+
with self._listen_context() as selector:
|
89
|
+
def loop():
|
90
|
+
while not self._should_shutdown:
|
91
|
+
ready = selector.select(poll_interval)
|
92
|
+
|
93
|
+
# bpo-35017: shutdown() called during select(), exit immediately.
|
94
|
+
if self._should_shutdown:
|
95
|
+
break # type: ignore[unreachable]
|
96
|
+
|
97
|
+
if ready:
|
98
|
+
try:
|
99
|
+
conn = self._binder.accept()
|
100
|
+
|
101
|
+
except OSError as exc:
|
102
|
+
if (on_error := self._on_error) is not None:
|
103
|
+
on_error(exc)
|
104
|
+
|
105
|
+
return
|
106
|
+
|
107
|
+
self._handler(conn)
|
108
|
+
|
109
|
+
yield bool(ready)
|
110
|
+
|
111
|
+
yield loop()
|
112
|
+
|
113
|
+
def run(self, poll_interval: ta.Optional[float] = None) -> None:
|
114
|
+
with self.loop_context(poll_interval=poll_interval) as loop:
|
115
|
+
for _ in loop:
|
116
|
+
pass
|
117
|
+
|
118
|
+
#
|
119
|
+
|
120
|
+
class _NOT_SET: # noqa
|
121
|
+
def __new__(cls, *args, **kwargs): # noqa
|
122
|
+
raise TypeError
|
123
|
+
|
124
|
+
def shutdown(
|
125
|
+
self,
|
126
|
+
block: bool = False,
|
127
|
+
timeout: ta.Union[float, None, ta.Type[_NOT_SET]] = _NOT_SET,
|
128
|
+
) -> None:
|
129
|
+
self._should_shutdown = True
|
130
|
+
|
131
|
+
if block:
|
132
|
+
if timeout is self._NOT_SET:
|
133
|
+
timeout = self._shutdown_timeout
|
134
|
+
|
135
|
+
if not self._is_shutdown.wait(timeout=timeout): # type: ignore
|
136
|
+
raise TimeoutError
|
137
|
+
|
138
|
+
#
|
139
|
+
|
140
|
+
def __enter__(self) -> 'SocketServer':
|
141
|
+
return self
|
142
|
+
|
143
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
144
|
+
self.shutdown()
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# @omlish-lite
|
2
|
+
# ruff: noqa: UP006 UP007
|
3
|
+
import threading
|
4
|
+
import time
|
5
|
+
import typing as ta
|
6
|
+
|
7
|
+
from ...lite.check import check
|
8
|
+
from ..addresses import SocketAndAddress
|
9
|
+
from .handlers import SocketServerHandler
|
10
|
+
|
11
|
+
|
12
|
+
##
|
13
|
+
|
14
|
+
|
15
|
+
class ThreadingSocketServerHandler:
|
16
|
+
def __init__(
|
17
|
+
self,
|
18
|
+
handler: SocketServerHandler,
|
19
|
+
*,
|
20
|
+
shutdown_timeout: ta.Optional[float] = None,
|
21
|
+
) -> None:
|
22
|
+
super().__init__()
|
23
|
+
|
24
|
+
self._handler = handler
|
25
|
+
self._shutdown_timeout = shutdown_timeout
|
26
|
+
|
27
|
+
self._lock = threading.RLock()
|
28
|
+
self._threads: ta.List[threading.Thread] = []
|
29
|
+
self._is_shutdown = False
|
30
|
+
|
31
|
+
@property
|
32
|
+
def handler(self) -> SocketServerHandler:
|
33
|
+
return self._handler
|
34
|
+
|
35
|
+
#
|
36
|
+
|
37
|
+
def __call__(self, conn: SocketAndAddress) -> None:
|
38
|
+
self.handle(conn)
|
39
|
+
|
40
|
+
def handle(self, conn: SocketAndAddress) -> None:
|
41
|
+
with self._lock:
|
42
|
+
check.state(not self._is_shutdown)
|
43
|
+
|
44
|
+
self._reap()
|
45
|
+
|
46
|
+
t = threading.Thread(
|
47
|
+
target=self._handler,
|
48
|
+
args=(conn,),
|
49
|
+
)
|
50
|
+
|
51
|
+
self._threads.append(t)
|
52
|
+
|
53
|
+
t.start()
|
54
|
+
|
55
|
+
#
|
56
|
+
|
57
|
+
def _reap(self) -> None:
|
58
|
+
with self._lock:
|
59
|
+
self._threads[:] = (thread for thread in self._threads if thread.is_alive())
|
60
|
+
|
61
|
+
def is_alive(self) -> bool:
|
62
|
+
with self._lock:
|
63
|
+
self._reap()
|
64
|
+
|
65
|
+
return bool(self._threads)
|
66
|
+
|
67
|
+
def join(self, timeout: ta.Optional[float] = None) -> None:
|
68
|
+
if timeout is not None:
|
69
|
+
deadline: ta.Optional[float] = time.time() + timeout
|
70
|
+
else:
|
71
|
+
deadline = None
|
72
|
+
|
73
|
+
def calc_timeout() -> ta.Optional[float]:
|
74
|
+
if deadline is None:
|
75
|
+
return None
|
76
|
+
|
77
|
+
tt = deadline - time.time()
|
78
|
+
if tt <= 0:
|
79
|
+
raise TimeoutError
|
80
|
+
|
81
|
+
return tt
|
82
|
+
|
83
|
+
if not (self._lock.acquire(timeout=calc_timeout() or -1)):
|
84
|
+
raise TimeoutError
|
85
|
+
|
86
|
+
try:
|
87
|
+
self._reap()
|
88
|
+
|
89
|
+
for t in self._threads:
|
90
|
+
t.join(timeout=calc_timeout())
|
91
|
+
|
92
|
+
if t.is_alive():
|
93
|
+
raise TimeoutError
|
94
|
+
|
95
|
+
finally:
|
96
|
+
self._lock.release()
|
97
|
+
|
98
|
+
#
|
99
|
+
|
100
|
+
class _NOT_SET: # noqa
|
101
|
+
def __new__(cls, *args, **kwargs): # noqa
|
102
|
+
raise TypeError
|
103
|
+
|
104
|
+
def shutdown(
|
105
|
+
self,
|
106
|
+
block: bool = False,
|
107
|
+
timeout: ta.Union[float, None, ta.Type[_NOT_SET]] = _NOT_SET,
|
108
|
+
) -> None:
|
109
|
+
self._is_shutdown = True
|
110
|
+
|
111
|
+
if block:
|
112
|
+
if timeout is self._NOT_SET:
|
113
|
+
timeout = self._shutdown_timeout
|
114
|
+
|
115
|
+
self.join(timeout=timeout) # type: ignore
|
116
|
+
|
117
|
+
#
|
118
|
+
|
119
|
+
def __enter__(self) -> 'ThreadingSocketServerHandler':
|
120
|
+
return self
|
121
|
+
|
122
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
123
|
+
self.shutdown()
|
omlish/subprocesses.py
CHANGED
@@ -20,6 +20,12 @@ SubprocessChannelOption = ta.Literal['pipe', 'stdout', 'devnull'] # ta.TypeAlia
|
|
20
20
|
##
|
21
21
|
|
22
22
|
|
23
|
+
# Valid channel type kwarg values:
|
24
|
+
# - A special flag negative int
|
25
|
+
# - A positive fd int
|
26
|
+
# - A file-like object
|
27
|
+
# - None
|
28
|
+
|
23
29
|
SUBPROCESS_CHANNEL_OPTION_VALUES: ta.Mapping[SubprocessChannelOption, int] = {
|
24
30
|
'pipe': subprocess.PIPE,
|
25
31
|
'stdout': subprocess.STDOUT,
|
@@ -65,6 +71,25 @@ def subprocess_close(
|
|
65
71
|
##
|
66
72
|
|
67
73
|
|
74
|
+
class VerboseCalledProcessError(subprocess.CalledProcessError):
|
75
|
+
@classmethod
|
76
|
+
def from_std(cls, e: subprocess.CalledProcessError) -> 'VerboseCalledProcessError':
|
77
|
+
return cls(
|
78
|
+
e.returncode,
|
79
|
+
e.cmd,
|
80
|
+
output=e.output,
|
81
|
+
stderr=e.stderr,
|
82
|
+
)
|
83
|
+
|
84
|
+
def __str__(self) -> str:
|
85
|
+
msg = super().__str__()
|
86
|
+
if self.output is not None:
|
87
|
+
msg += f' Output: {self.output!r}'
|
88
|
+
if self.stderr is not None:
|
89
|
+
msg += f' Stderr: {self.stderr!r}'
|
90
|
+
return msg
|
91
|
+
|
92
|
+
|
68
93
|
class BaseSubprocesses(abc.ABC): # noqa
|
69
94
|
DEFAULT_LOGGER: ta.ClassVar[ta.Optional[logging.Logger]] = None
|
70
95
|
|
@@ -98,16 +123,31 @@ class BaseSubprocesses(abc.ABC): # noqa
|
|
98
123
|
if extra_env:
|
99
124
|
self._log.debug('Subprocesses.prepare_args: extra_env=%r', extra_env)
|
100
125
|
|
126
|
+
#
|
127
|
+
|
101
128
|
if extra_env:
|
102
129
|
env = {**(env if env is not None else os.environ), **extra_env}
|
103
130
|
|
131
|
+
#
|
132
|
+
|
104
133
|
if quiet and 'stderr' not in kwargs:
|
105
134
|
if self._log and not self._log.isEnabledFor(logging.DEBUG):
|
106
135
|
kwargs['stderr'] = subprocess.DEVNULL
|
107
136
|
|
137
|
+
for chk in ('stdout', 'stderr'):
|
138
|
+
try:
|
139
|
+
chv = kwargs[chk]
|
140
|
+
except KeyError:
|
141
|
+
continue
|
142
|
+
kwargs[chk] = SUBPROCESS_CHANNEL_OPTION_VALUES.get(chv, chv)
|
143
|
+
|
144
|
+
#
|
145
|
+
|
108
146
|
if not shell:
|
109
147
|
cmd = subprocess_maybe_shell_wrap_exec(*cmd)
|
110
148
|
|
149
|
+
#
|
150
|
+
|
111
151
|
return cmd, dict(
|
112
152
|
env=env,
|
113
153
|
shell=shell,
|
@@ -115,35 +155,57 @@ class BaseSubprocesses(abc.ABC): # noqa
|
|
115
155
|
)
|
116
156
|
|
117
157
|
@contextlib.contextmanager
|
118
|
-
def wrap_call(
|
158
|
+
def wrap_call(
|
159
|
+
self,
|
160
|
+
*cmd: ta.Any,
|
161
|
+
raise_verbose: bool = False,
|
162
|
+
**kwargs: ta.Any,
|
163
|
+
) -> ta.Iterator[None]:
|
119
164
|
start_time = time.time()
|
120
165
|
try:
|
121
166
|
if self._log:
|
122
167
|
self._log.debug('Subprocesses.wrap_call.try: cmd=%r', cmd)
|
168
|
+
|
123
169
|
yield
|
124
170
|
|
125
171
|
except Exception as exc: # noqa
|
126
172
|
if self._log:
|
127
173
|
self._log.debug('Subprocesses.wrap_call.except: exc=%r', exc)
|
174
|
+
|
175
|
+
if (
|
176
|
+
raise_verbose and
|
177
|
+
isinstance(exc, subprocess.CalledProcessError) and
|
178
|
+
not isinstance(exc, VerboseCalledProcessError) and
|
179
|
+
(exc.output is not None or exc.stderr is not None)
|
180
|
+
):
|
181
|
+
raise VerboseCalledProcessError.from_std(exc) from exc
|
182
|
+
|
128
183
|
raise
|
129
184
|
|
130
185
|
finally:
|
131
186
|
end_time = time.time()
|
132
187
|
elapsed_s = end_time - start_time
|
188
|
+
|
133
189
|
if self._log:
|
134
|
-
self._log.debug('
|
190
|
+
self._log.debug('Subprocesses.wrap_call.finally: elapsed_s=%f cmd=%r', elapsed_s, cmd)
|
135
191
|
|
136
192
|
@contextlib.contextmanager
|
137
193
|
def prepare_and_wrap(
|
138
194
|
self,
|
139
195
|
*cmd: ta.Any,
|
196
|
+
raise_verbose: bool = False,
|
140
197
|
**kwargs: ta.Any,
|
141
198
|
) -> ta.Iterator[ta.Tuple[
|
142
199
|
ta.Tuple[ta.Any, ...],
|
143
200
|
ta.Dict[str, ta.Any],
|
144
201
|
]]:
|
145
202
|
cmd, kwargs = self.prepare_args(*cmd, **kwargs)
|
146
|
-
|
203
|
+
|
204
|
+
with self.wrap_call(
|
205
|
+
*cmd,
|
206
|
+
raise_verbose=raise_verbose,
|
207
|
+
**kwargs,
|
208
|
+
):
|
147
209
|
yield cmd, kwargs
|
148
210
|
|
149
211
|
#
|
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.manifests.json,sha256=YGmAnUBszmosQQ_7Hh2wwtDiYdYZ4unNKYzOtALuels,7968
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=0BtXUJi7KSCGQMkzet9GL1mr4dSvaRR9Jv-gAz1olhc,3380
|
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
|
@@ -11,7 +11,7 @@ omlish/libc.py,sha256=8r7Ejyhttk9ruCfBkxNTrlzir5WPbDE2vmY7VPlceMA,15362
|
|
11
11
|
omlish/outcome.py,sha256=ABIE0zjjTyTNtn-ZqQ_9_mUzLiBQ3sDAyqc9JVD8N2k,7852
|
12
12
|
omlish/runmodule.py,sha256=PWvuAaJ9wQQn6bx9ftEL3_d04DyotNn8dR_twm2pgw0,700
|
13
13
|
omlish/shlex.py,sha256=bsW2XUD8GiMTUTDefJejZ5AyqT1pTgWMPD0BMoF02jE,248
|
14
|
-
omlish/subprocesses.py,sha256=
|
14
|
+
omlish/subprocesses.py,sha256=c7arxsQ7JiaNCmK3GKqwRO6BwrvxeK7eez8A4SrvGBo,10199
|
15
15
|
omlish/sync.py,sha256=QJ79kxmIqDP9SeHDoZAf--DpFIhDQe1jACy8H4N0yZI,2928
|
16
16
|
omlish/antlr/__init__.py,sha256=88bMl_28cfSKslgOkMGYXqALgsHz3KC4LFvAVtzj7k8,89
|
17
17
|
omlish/antlr/delimit.py,sha256=3Byvh9_Ip8ftM_SeSEmMbnNo1jrxk-xm8HnHDp_nDaI,3466
|
@@ -93,7 +93,7 @@ omlish/asyncs/flavors.py,sha256=1mNxGNRVmjUHzA13K5ht8vdJv4CLEmzYTQ6BZXr1520,4866
|
|
93
93
|
omlish/asyncs/trio.py,sha256=fmZ5b_lKdVV8NQ3euCUutWgnkqTFzSnOjvJSA_jvmrE,367
|
94
94
|
omlish/asyncs/trio_asyncio.py,sha256=oqdOHy0slj9PjVxaDf3gJkq9AAgg7wYZbB469jOftVw,1327
|
95
95
|
omlish/asyncs/asyncio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
96
|
-
omlish/asyncs/asyncio/all.py,sha256=
|
96
|
+
omlish/asyncs/asyncio/all.py,sha256=KpTanEtpTlc3rqv5SyiJaJGb_DXBzp_WKLhlRq6lrhY,212
|
97
97
|
omlish/asyncs/asyncio/asyncio.py,sha256=3BMhVIF-QTjsFRGDtNYlRbBqKPCA3_AwJsjJoIWdM8k,1783
|
98
98
|
omlish/asyncs/asyncio/channels.py,sha256=ZbmsEmdK1fV96liHdcVpRqA2dAMkXJt4Q3rFAg3YOIw,1074
|
99
99
|
omlish/asyncs/asyncio/streams.py,sha256=Uc9PCWSfBqrK2kdVtfjjQU1eaYTWYmZm8QISDj2xiuw,1004
|
@@ -169,8 +169,8 @@ omlish/configs/processing/matching.py,sha256=R64RxpPB1uX5Ztvvk2dQ2xi_xwlaxkxQgZw
|
|
169
169
|
omlish/configs/processing/names.py,sha256=weHmaTclzgM9lUn3aBtw-kwZ3mc2N-CZlFg3Kd_UsKo,1093
|
170
170
|
omlish/configs/processing/rewriting.py,sha256=v7PfHtuTn5v_5Y6Au7oMN2Z0nxAMy1iYyO5CXnTvZhs,4226
|
171
171
|
omlish/configs/processing/strings.py,sha256=qFS2oh6z02IaM_q4lTKLdufzkJqAJ6J-Qjrz5S-QJoM,826
|
172
|
-
omlish/dataclasses/__init__.py,sha256=
|
173
|
-
omlish/dataclasses/utils.py,sha256=
|
172
|
+
omlish/dataclasses/__init__.py,sha256=4LYQCg0kqBNwexcXvK6drjxdi79sMvqa4augNhCBHLU,1543
|
173
|
+
omlish/dataclasses/utils.py,sha256=N2seT8cJtfOv-41D7F3E-q4us-FCTQmnxxPv3dt1OcI,3796
|
174
174
|
omlish/dataclasses/impl/LICENSE,sha256=Oy-B_iHRgcSZxZolbI4ZaEVdZonSaaqFNzv7avQdo78,13936
|
175
175
|
omlish/dataclasses/impl/__init__.py,sha256=zqGBC5gSbjJxaqG_zS1LL1PX-zAfhIua8UqOE4IwO2k,789
|
176
176
|
omlish/dataclasses/impl/api.py,sha256=p7W519_EnDAWlkOVS-4BpP4SxadWIiUzC3RldSoB28o,6431
|
@@ -224,7 +224,11 @@ omlish/docker/consts.py,sha256=wvwfUtEFrEWZKfREWqSMrx8xjjl8P5MNUSF6qzzgJHY,70
|
|
224
224
|
omlish/docker/detect.py,sha256=Qrdbosm2wJkxKDuy8gaGmbQoxk4Wnp1HJjAEz58NA8Y,614
|
225
225
|
omlish/docker/hub.py,sha256=7LIuJGdA-N1Y1dmo50ynKM1KUTcnQM_5XbtPbdT_QLU,3940
|
226
226
|
omlish/docker/manifests.py,sha256=LR4FpOGNUT3bZQ-gTjB6r_-1C3YiG30QvevZjrsVUQM,7068
|
227
|
+
omlish/docker/portrelay.py,sha256=QlRoTnQXs5INguR7XOj1xH0gNdL9SUeZm5z45DUctXo,1222
|
227
228
|
omlish/docker/timebomb.py,sha256=A_pgIDaXKsQwPiikrCTgIJl91gwYqkPGFY6j-Naq07Q,342
|
229
|
+
omlish/docker/oci/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
230
|
+
omlish/docker/oci/data.py,sha256=4KtSxziT70BhF30ozQ1SCfX4y0LT_5x0CuOKC4zrEV4,2616
|
231
|
+
omlish/docker/oci/media.py,sha256=fJ8VcU-edDpg-FyJQamw-sUlhTghkC-WQ1TC4MiRpFU,4499
|
228
232
|
omlish/formats/__init__.py,sha256=T0AG1gFnqQ5JiHN0UPQjQ-7g5tnxMIG-mgOvMYExYAM,21
|
229
233
|
omlish/formats/cbor.py,sha256=o_Hbe4kthO9CeXK-FySrw0dHVlrdyTo2Y8PpGRDfZ3c,514
|
230
234
|
omlish/formats/cloudpickle.py,sha256=16si4yUp_pAdDWGECAWf6HLA2PwSANGGgDoMLGZUem8,579
|
@@ -260,7 +264,7 @@ omlish/formats/json/stream/errors.py,sha256=c8M8UAYmIZ-vWZLeKD2jMj4EDCJbr9QR8Jq_
|
|
260
264
|
omlish/formats/json/stream/lex.py,sha256=ItsWvtl5SZH-HwQtPy8Cpf4nszqDzvUTdIOEmSRiZ-E,6807
|
261
265
|
omlish/formats/json/stream/parse.py,sha256=JuYmXwtTHmQJTFKoJNoEHUpCPxXdl_gvKPykVXgED34,6208
|
262
266
|
omlish/formats/json/stream/render.py,sha256=NtmDsN92xZi5dkgSSuMeMXMAiJblmjz1arB4Ft7vBhc,3715
|
263
|
-
omlish/formats/json5/Json5.g4,sha256=
|
267
|
+
omlish/formats/json5/Json5.g4,sha256=ZUmgJPvj8lSMUD_v3wijp10ZQExYB5mu5Q089dYEJSU,2389
|
264
268
|
omlish/formats/json5/__init__.py,sha256=BsjPz5zJDji3GjQ8x8hWvcl1GYPV_ZIHnE3c2Sr8aTU,102
|
265
269
|
omlish/formats/json5/codec.py,sha256=ldnxCRo0JP1fkGLt0mMxJlLvNxqIF_1KUCcSp1HtI-M,452
|
266
270
|
omlish/formats/json5/errors.py,sha256=AHkR9ySjAoQdUrizpqgL8fg0M5oe5mHZkml3KZHEvC4,38
|
@@ -297,7 +301,7 @@ omlish/http/consts.py,sha256=7BJ4D1MdIvqBcepkgCfBFHolgTwbOlqsOEiee_IjxOA,2289
|
|
297
301
|
omlish/http/cookies.py,sha256=uuOYlHR6e2SC3GM41V0aozK10nef9tYg83Scqpn5-HM,6351
|
298
302
|
omlish/http/dates.py,sha256=Otgp8wRxPgNGyzx8LFowu1vC4EKJYARCiAwLFncpfHM,2875
|
299
303
|
omlish/http/encodings.py,sha256=w2WoKajpaZnQH8j-IBvk5ZFL2O2pAU_iBvZnkocaTlw,164
|
300
|
-
omlish/http/handlers.py,sha256=
|
304
|
+
omlish/http/handlers.py,sha256=twe1VYYlIX0e_unFNtt5moU-VbtG29IuTu4RWS1vrn4,1052
|
301
305
|
omlish/http/headers.py,sha256=ZMmjrEiYjzo0YTGyK0YsvjdwUazktGqzVVYorY4fd44,5081
|
302
306
|
omlish/http/json.py,sha256=9XwAsl4966Mxrv-1ytyCqhcE6lbBJw-0_tFZzGszgHE,7440
|
303
307
|
omlish/http/jwt.py,sha256=6Rigk1WrJ059DY4jDIKnxjnChWb7aFdermj2AI2DSvk,4346
|
@@ -309,7 +313,7 @@ omlish/http/versions.py,sha256=wSiOXPiClVjkVgSU_VmxkoD1SUYGaoPbP0U5Aw-Ufg8,409
|
|
309
313
|
omlish/http/wsgi.py,sha256=czZsVUX-l2YTlMrUjKN49wRoP4rVpS0qpeBn4O5BoMY,948
|
310
314
|
omlish/http/coro/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
311
315
|
omlish/http/coro/fdio.py,sha256=ajj_lekRockGwQEw8m_mi6RO9-o6hnC9ITiwtZe3y-s,4017
|
312
|
-
omlish/http/coro/server.py,sha256
|
316
|
+
omlish/http/coro/server.py,sha256=IhdBv-Cx09FG6ADNXfysJV6v7i1gU7dCHLx9Bt_BieM,18799
|
313
317
|
omlish/inject/__init__.py,sha256=n0RC9UDGsBQQ39cST39-XJqJPq2M0tnnh9yJubW9azo,1891
|
314
318
|
omlish/inject/binder.py,sha256=DAbc8TZi5w8Mna0TUtq0mT4jeDVA7i7SlBtOFrh2swc,4185
|
315
319
|
omlish/inject/bindings.py,sha256=pLXn2U3kvmAS-68IOG-tr77DbiI-wp9hGyy4lhG6_H8,525
|
@@ -371,7 +375,7 @@ omlish/io/fdio/pollers.py,sha256=yNadAt3W5wd90PFmd3vD77bq5QwoVb2A6SM2JjZpKRs,550
|
|
371
375
|
omlish/iterators/__init__.py,sha256=yMavf5FofiS1EU4UFuWPXiFZ03W0H-y7MuMxW8FUaEE,358
|
372
376
|
omlish/iterators/iterators.py,sha256=ghI4dO6WPyyFOLTIIMaHQ_IOy2xXaFpGPqveZ5YGIBU,3158
|
373
377
|
omlish/iterators/recipes.py,sha256=53mkexitMhkwXQZbL6DrhpT0WePQ_56uXd5Jaw3DfzI,467
|
374
|
-
omlish/iterators/tools.py,sha256=
|
378
|
+
omlish/iterators/tools.py,sha256=Pi4ybXytUXVZ3xwK89xpPImQfYYId9p1vIFQvVqVLqA,2551
|
375
379
|
omlish/iterators/unique.py,sha256=0jAX3kwzVfRNhe0Tmh7kVP_Q2WBIn8POo_O-rgFV0rQ,1390
|
376
380
|
omlish/lang/__init__.py,sha256=sY7YSgN772n48qWlR-mwuOOCOwRF5Fh421gZqZWxYlw,4042
|
377
381
|
omlish/lang/cached.py,sha256=92TvRZQ6sWlm7dNn4hgl7aWKbX0J1XUEo3DRjBpgVQk,7834
|
@@ -383,7 +387,7 @@ omlish/lang/descriptors.py,sha256=RRBbkMgTzg82fFFE4D0muqobpM-ZZaOta6yB1lpX3s8,66
|
|
383
387
|
omlish/lang/exceptions.py,sha256=qJBo3NU1mOWWm-NhQUHCY5feYXR3arZVyEHinLsmRH4,47
|
384
388
|
omlish/lang/functions.py,sha256=t9nsnWwhsibG0w908VMx-_pRM5tZfruE3faPxrCWTbI,4160
|
385
389
|
omlish/lang/generators.py,sha256=5LX17j-Ej3QXhwBgZvRTm_dq3n9veC4IOUcVmvSu2vU,5243
|
386
|
-
omlish/lang/imports.py,sha256=
|
390
|
+
omlish/lang/imports.py,sha256=oGigWiLkLog29mWWYdu7untyX--K1SueFmKzCpXdtug,9612
|
387
391
|
omlish/lang/iterables.py,sha256=HOjcxOwyI5bBApDLsxRAGGhTTmw7fdZl2kEckxRVl-0,1994
|
388
392
|
omlish/lang/maybes.py,sha256=1RN7chX_x2XvgUwryZRz0W7hAX-be3eEFcFub5vvf6M,3417
|
389
393
|
omlish/lang/objects.py,sha256=LOC3JvX1g5hPxJ7Sv2TK9kNkAo9c8J-Jw2NmClR_rkA,4576
|
@@ -411,7 +415,7 @@ omlish/lite/cached.py,sha256=O7ozcoDNFm1Hg2wtpHEqYSp_i_nCLNOP6Ueq_Uk-7mU,1300
|
|
411
415
|
omlish/lite/check.py,sha256=OLwtE2x6nlbGx4vS3Rda7zMHpgqzDSLJminTAX2lqLA,13529
|
412
416
|
omlish/lite/configs.py,sha256=Ev_19sbII67pTWzInYjYqa9VyTiZBvyjhZqyG8TtufE,908
|
413
417
|
omlish/lite/contextmanagers.py,sha256=ciaMl0D3QDHToM7M28-kwZ-Q48LtwgCxiud3nekgutA,2863
|
414
|
-
omlish/lite/dataclasses.py,sha256=
|
418
|
+
omlish/lite/dataclasses.py,sha256=k1588egoF3h_Kb21tuQb8WyJ9wxhT06EztFvaKOHzNU,1115
|
415
419
|
omlish/lite/inject.py,sha256=qBUftFeXMiRgANYbNS2e7TePMYyFAcuLgsJiLyMTW5o,28769
|
416
420
|
omlish/lite/json.py,sha256=7-02Ny4fq-6YAu5ynvqoijhuYXWpLmfCI19GUeZnb1c,740
|
417
421
|
omlish/lite/logs.py,sha256=CWFG0NKGhqNeEgryF5atN2gkPYbUdTINEw_s1phbINM,51
|
@@ -427,13 +431,15 @@ omlish/lite/types.py,sha256=fP5EMyBdEp2LmDxcHjUDtwAMdR06ISr9lKOL7smWfHM,140
|
|
427
431
|
omlish/lite/typing.py,sha256=U3-JaEnkDSYxK4tsu_MzUn3RP6qALBe5FXQXpD-licE,1090
|
428
432
|
omlish/logs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
429
433
|
omlish/logs/abc.py,sha256=ho4ABKYMKX-V7g4sp1BByuOLzslYzLlQ0MESmjEpT-o,8005
|
430
|
-
omlish/logs/all.py,sha256=
|
434
|
+
omlish/logs/all.py,sha256=Er2NIcDvlMpuAcRr9b_uMHeoERU7I6lu5oLrDGRdV0U,728
|
435
|
+
omlish/logs/callers.py,sha256=W0BdEtuGkQ0JM-FCsXQIBQCsNUbIsbDrtCaJy9DStk4,1143
|
431
436
|
omlish/logs/color.py,sha256=CM-ceoPXs0j5_klnZDJkFCFRgHOToFzJyLjC6LsnPEk,665
|
432
437
|
omlish/logs/configs.py,sha256=XOc8rWxfPpPMxJESVD2mLCUoLtbQnGnZwvYhhqe7DD8,772
|
433
438
|
omlish/logs/filters.py,sha256=2noFRyBez3y519fpfsDSt1vo8wX-85b8sMXZi5o_xyE,208
|
434
439
|
omlish/logs/handlers.py,sha256=zgSnKQA5q9Fu7T0Nkd7twog9H1Wg9-bDCzz4_F1TOBo,319
|
435
440
|
omlish/logs/json.py,sha256=zyqMWpZY3lk4WRk4wgmataBomGX9S3iDsydiM1sS-lI,1366
|
436
441
|
omlish/logs/noisy.py,sha256=Ubc-eTH6ZbGYsLfUUi69JAotwuUwzb-SJBeGo_0dIZI,348
|
442
|
+
omlish/logs/protocol.py,sha256=NzyCeNBN-fyKpJinhECfjUQSd5MxZLiYbuLCTtW6QUU,4500
|
437
443
|
omlish/logs/proxy.py,sha256=A-ROPUUAlF397qTbEqhel6YhQMstNuXL3Xmts7w9dAo,2347
|
438
444
|
omlish/logs/standard.py,sha256=FbKdF2Z4Na5i2TNwKn0avLJXyICe2JKsPufjvKCHGn0,3162
|
439
445
|
omlish/logs/utils.py,sha256=mzHrZ9ji75p5A8qR29eUr05CBAHMb8J753MSkID_VaQ,393
|
@@ -444,7 +450,7 @@ omlish/marshal/__init__.py,sha256=iVA7n31L08Bdub6HKPvYOXVvDhk2CMA6rPeKDL_u1to,22
|
|
444
450
|
omlish/marshal/any.py,sha256=e82OyYK3Emm1P1ClnsnxP7fIWC2iNVyW0H5nK4mLmWM,779
|
445
451
|
omlish/marshal/base.py,sha256=HEzfby-PgGzIhiRpBkFrkw5-hKacRSC5W_jwLjT8aYw,6740
|
446
452
|
omlish/marshal/base64.py,sha256=F-3ogJdcFCtWINRgJgWT0rErqgx6f4qahhcg8OrkqhE,1089
|
447
|
-
omlish/marshal/dataclasses.py,sha256=
|
453
|
+
omlish/marshal/dataclasses.py,sha256=ZpfNaIdhKwWouWkoQGuequKwrEeehbz9QSQoW3acyPo,7756
|
448
454
|
omlish/marshal/datetimes.py,sha256=0ffg8cEvx9SMKIXZGD9b7MqpLfmgw0uKKdn6YTfoqok,3714
|
449
455
|
omlish/marshal/enums.py,sha256=CMAbx6RI2EcQoo7SoD-5q2l-3DFKreWMiOxs6mFpl_4,1472
|
450
456
|
omlish/marshal/exceptions.py,sha256=jwQWn4LcPnadT2KRI_1JJCOSkwWh0yHnYK9BmSkNN4U,302
|
@@ -503,9 +509,14 @@ omlish/secrets/pwhash.py,sha256=Goktn-swmC6PXqfRBnDrH_Lr42vjckT712UyErPjzkw,4102
|
|
503
509
|
omlish/secrets/secrets.py,sha256=cnDGBoPknVxsCN04_gqcJT_7Ebk3iO3VPkRZ2oMjkMw,7868
|
504
510
|
omlish/secrets/subprocesses.py,sha256=ffjfbgPbEE_Pwb_87vG4yYR2CGZy3I31mHNCo_0JtHw,1212
|
505
511
|
omlish/sockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
506
|
-
omlish/sockets/addresses.py,sha256=
|
507
|
-
omlish/sockets/
|
508
|
-
omlish/sockets/
|
512
|
+
omlish/sockets/addresses.py,sha256=QGK-5smlg5owx3PEw9qSfSHQ5mkAYumUpbaVR4qvcpM,1442
|
513
|
+
omlish/sockets/bind.py,sha256=F5PATao0xUEoZ0unZbro2tPTECDtj1B6lS3ygEvIxUs,7750
|
514
|
+
omlish/sockets/handlers.py,sha256=cVMKG3dn_tJlz6aM0WUL1uQ03F7VQmmKn9yJlOwKE6g,226
|
515
|
+
omlish/sockets/io.py,sha256=lfhTkB7NnAIx9kuQhAkwgsEUXY78Mp1_WtYrIQNS_k8,1408
|
516
|
+
omlish/sockets/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
517
|
+
omlish/sockets/server/handlers.py,sha256=aoWZtDKPboHj3YAR-qHblnEGpz_Nx8mEajV_LxXUBRw,2440
|
518
|
+
omlish/sockets/server/server.py,sha256=ZLYjW_MmHfMGQ2qSMRFMKLwqPqGCCSf4ORiZjQd59MA,4144
|
519
|
+
omlish/sockets/server/threading.py,sha256=YmW3Ym_p5j_F4SIH9BgRHIObywjq1HS39j9CGWIcMAY,2856
|
509
520
|
omlish/specs/__init__.py,sha256=zZwF8yXTEkSstYtORkDhVLK-_hWU8WOJCuBpognb_NY,118
|
510
521
|
omlish/specs/jmespath/LICENSE,sha256=IH-ZZlZkS8XMkf_ubNVD1aYHQ2l_wd0tmHtXrCcYpRU,1113
|
511
522
|
omlish/specs/jmespath/__init__.py,sha256=9tsrquw1kXe1KAhTP3WeL0GlGBiTguQVxsC-lUYTWP4,2087
|
@@ -626,9 +637,9 @@ omlish/text/indent.py,sha256=YjtJEBYWuk8--b9JU_T6q4yxV85_TR7VEVr5ViRCFwk,1336
|
|
626
637
|
omlish/text/minja.py,sha256=jZC-fp3Xuhx48ppqsf2Sf1pHbC0t8XBB7UpUUoOk2Qw,5751
|
627
638
|
omlish/text/parts.py,sha256=7vPF1aTZdvLVYJ4EwBZVzRSy8XB3YqPd7JwEnNGGAOo,6495
|
628
639
|
omlish/text/random.py,sha256=jNWpqiaKjKyTdMXC-pWAsSC10AAP-cmRRPVhm59ZWLk,194
|
629
|
-
omlish-0.0.0.
|
630
|
-
omlish-0.0.0.
|
631
|
-
omlish-0.0.0.
|
632
|
-
omlish-0.0.0.
|
633
|
-
omlish-0.0.0.
|
634
|
-
omlish-0.0.0.
|
640
|
+
omlish-0.0.0.dev218.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
641
|
+
omlish-0.0.0.dev218.dist-info/METADATA,sha256=-vMqTXr2Q_gjsOk2hxSEXQXb9eWwZ4vVabWD7mQjgD8,4176
|
642
|
+
omlish-0.0.0.dev218.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
643
|
+
omlish-0.0.0.dev218.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
644
|
+
omlish-0.0.0.dev218.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
645
|
+
omlish-0.0.0.dev218.dist-info/RECORD,,
|