omlish 0.0.0.dev149__py3-none-any.whl → 0.0.0.dev151__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/argparse/cli.py +19 -23
- omlish/check.py +49 -464
- omlish/docker/__init__.py +0 -37
- omlish/docker/all.py +31 -0
- omlish/docker/consts.py +4 -0
- omlish/{lite/docker.py → docker/detect.py} +16 -1
- omlish/docker/{helpers.py → timebomb.py} +0 -15
- omlish/http/__init__.py +0 -48
- omlish/http/all.py +48 -0
- omlish/{lite/http → http}/coroserver.py +11 -12
- omlish/{lite/http → http}/handlers.py +2 -1
- omlish/{lite/http → http}/parsing.py +1 -0
- omlish/{lite/http → http}/versions.py +1 -0
- omlish/io/buffers.py +6 -8
- omlish/io/fdio/corohttp.py +10 -13
- omlish/io/fdio/handlers.py +2 -2
- omlish/lite/asyncio/subprocesses.py +9 -12
- omlish/lite/check.py +438 -80
- omlish/lite/contextmanagers.py +3 -4
- omlish/lite/inject.py +12 -16
- omlish/lite/marshal.py +7 -8
- omlish/lite/socketserver.py +2 -2
- omlish/testing/pytest/plugins/switches.py +1 -1
- {omlish-0.0.0.dev149.dist-info → omlish-0.0.0.dev151.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev149.dist-info → omlish-0.0.0.dev151.dist-info}/RECORD +30 -28
- omlish/lite/http/__init__.py +0 -0
- {omlish-0.0.0.dev149.dist-info → omlish-0.0.0.dev151.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev149.dist-info → omlish-0.0.0.dev151.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev149.dist-info → omlish-0.0.0.dev151.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev149.dist-info → omlish-0.0.0.dev151.dist-info}/top_level.txt +0 -0
omlish/docker/all.py
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
from .cli import ( # noqa
|
2
|
+
Inspect,
|
3
|
+
Port,
|
4
|
+
PsItem,
|
5
|
+
cli_inspect,
|
6
|
+
cli_ps,
|
7
|
+
has_cli,
|
8
|
+
parse_port,
|
9
|
+
)
|
10
|
+
|
11
|
+
from .compose import ( # noqa
|
12
|
+
ComposeConfig,
|
13
|
+
get_compose_port,
|
14
|
+
)
|
15
|
+
|
16
|
+
from .detect import ( # noqa
|
17
|
+
DOCKER_HOST_PLATFORM_KEY,
|
18
|
+
get_docker_host_platform,
|
19
|
+
is_likely_in_docker,
|
20
|
+
)
|
21
|
+
|
22
|
+
from .hub import ( # noqa
|
23
|
+
HubRepoInfo,
|
24
|
+
get_hub_repo_info,
|
25
|
+
select_latest_tag,
|
26
|
+
split_tag_suffix,
|
27
|
+
)
|
28
|
+
|
29
|
+
from .timebomb import ( # noqa
|
30
|
+
timebomb_payload,
|
31
|
+
)
|
omlish/docker/consts.py
ADDED
@@ -1,8 +1,23 @@
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
2
|
+
# @omlish-lite
|
3
|
+
import os
|
1
4
|
import re
|
2
5
|
import sys
|
6
|
+
import typing as ta
|
3
7
|
|
4
8
|
|
5
|
-
|
9
|
+
##
|
10
|
+
|
11
|
+
|
12
|
+
# Set by pyproject, docker-dev script
|
13
|
+
DOCKER_HOST_PLATFORM_KEY = 'DOCKER_HOST_PLATFORM'
|
14
|
+
|
15
|
+
|
16
|
+
def get_docker_host_platform() -> ta.Optional[str]:
|
17
|
+
return os.environ.get(DOCKER_HOST_PLATFORM_KEY)
|
18
|
+
|
19
|
+
|
20
|
+
##
|
6
21
|
|
7
22
|
|
8
23
|
_LIKELY_IN_DOCKER_PATTERN = re.compile(r'^overlay / .*/(docker|desktop-containerd)/')
|
@@ -1,10 +1,6 @@
|
|
1
|
-
import os
|
2
1
|
import shlex
|
3
2
|
|
4
3
|
|
5
|
-
##
|
6
|
-
|
7
|
-
|
8
4
|
_DEFAULT_TIMEBOMB_NAME = '-'.join([*__name__.split('.'), 'timebomb'])
|
9
5
|
|
10
6
|
|
@@ -16,14 +12,3 @@ def timebomb_payload(delay_s: float, name: str = _DEFAULT_TIMEBOMB_NAME) -> str:
|
|
16
12
|
'sh -c \'killall5 -9 -o $PPID -o $$ ; kill 1\''
|
17
13
|
') &'
|
18
14
|
)
|
19
|
-
|
20
|
-
|
21
|
-
##
|
22
|
-
|
23
|
-
|
24
|
-
# Set by pyproject, docker-dev script
|
25
|
-
DOCKER_HOST_PLATFORM_KEY = 'DOCKER_HOST_PLATFORM'
|
26
|
-
|
27
|
-
|
28
|
-
def get_docker_host_platform() -> str | None:
|
29
|
-
return os.environ.get(DOCKER_HOST_PLATFORM_KEY)
|
omlish/http/__init__.py
CHANGED
@@ -1,48 +0,0 @@
|
|
1
|
-
from . import consts # noqa
|
2
|
-
|
3
|
-
from .clients import ( # noqa
|
4
|
-
HttpClient,
|
5
|
-
HttpClientError,
|
6
|
-
HttpRequest,
|
7
|
-
HttpResponse,
|
8
|
-
HttpxHttpClient,
|
9
|
-
UrllibHttpClient,
|
10
|
-
client,
|
11
|
-
request,
|
12
|
-
)
|
13
|
-
|
14
|
-
from .cookies import ( # noqa
|
15
|
-
CookieTooBigError,
|
16
|
-
dump_cookie,
|
17
|
-
parse_cookie,
|
18
|
-
)
|
19
|
-
|
20
|
-
from .dates import ( # noqa
|
21
|
-
http_date,
|
22
|
-
parse_date,
|
23
|
-
)
|
24
|
-
|
25
|
-
from .encodings import ( # noqa
|
26
|
-
latin1_decode,
|
27
|
-
latin1_encode,
|
28
|
-
)
|
29
|
-
|
30
|
-
from .headers import ( # noqa
|
31
|
-
CanHttpHeaders,
|
32
|
-
HttpHeaders,
|
33
|
-
headers,
|
34
|
-
)
|
35
|
-
|
36
|
-
from .json import ( # noqa
|
37
|
-
JSON_TAGGER,
|
38
|
-
JsonTag,
|
39
|
-
JsonTagger,
|
40
|
-
json_dumps,
|
41
|
-
json_loads,
|
42
|
-
)
|
43
|
-
|
44
|
-
from .multipart import ( # noqa
|
45
|
-
MultipartData,
|
46
|
-
MultipartEncoder,
|
47
|
-
MultipartField,
|
48
|
-
)
|
omlish/http/all.py
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
from . import consts # noqa
|
2
|
+
|
3
|
+
from .clients import ( # noqa
|
4
|
+
HttpClient,
|
5
|
+
HttpClientError,
|
6
|
+
HttpRequest,
|
7
|
+
HttpResponse,
|
8
|
+
HttpxHttpClient,
|
9
|
+
UrllibHttpClient,
|
10
|
+
client,
|
11
|
+
request,
|
12
|
+
)
|
13
|
+
|
14
|
+
from .cookies import ( # noqa
|
15
|
+
CookieTooBigError,
|
16
|
+
dump_cookie,
|
17
|
+
parse_cookie,
|
18
|
+
)
|
19
|
+
|
20
|
+
from .dates import ( # noqa
|
21
|
+
http_date,
|
22
|
+
parse_date,
|
23
|
+
)
|
24
|
+
|
25
|
+
from .encodings import ( # noqa
|
26
|
+
latin1_decode,
|
27
|
+
latin1_encode,
|
28
|
+
)
|
29
|
+
|
30
|
+
from .headers import ( # noqa
|
31
|
+
CanHttpHeaders,
|
32
|
+
HttpHeaders,
|
33
|
+
headers,
|
34
|
+
)
|
35
|
+
|
36
|
+
from .json import ( # noqa
|
37
|
+
JSON_TAGGER,
|
38
|
+
JsonTag,
|
39
|
+
JsonTagger,
|
40
|
+
json_dumps,
|
41
|
+
json_loads,
|
42
|
+
)
|
43
|
+
|
44
|
+
from .multipart import ( # noqa
|
45
|
+
MultipartData,
|
46
|
+
MultipartEncoder,
|
47
|
+
MultipartField,
|
48
|
+
)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
+
# @omlish-lite
|
2
3
|
# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
3
4
|
# --------------------------------------------
|
4
5
|
#
|
@@ -62,11 +63,9 @@ import textwrap
|
|
62
63
|
import time
|
63
64
|
import typing as ta
|
64
65
|
|
65
|
-
from ..check import
|
66
|
-
from ..
|
67
|
-
from ..
|
68
|
-
from ..socket import SocketAddress
|
69
|
-
from ..socket import SocketHandler
|
66
|
+
from ..lite.check import check
|
67
|
+
from ..lite.socket import SocketAddress
|
68
|
+
from ..lite.socket import SocketHandler
|
70
69
|
from .handlers import HttpHandler
|
71
70
|
from .handlers import HttpHandlerRequest
|
72
71
|
from .handlers import UnsupportedMethodHttpHandlerError
|
@@ -406,13 +405,13 @@ class CoroHttpServer:
|
|
406
405
|
yield o
|
407
406
|
|
408
407
|
elif isinstance(o, self.AnyReadIo):
|
409
|
-
i =
|
408
|
+
i = check.isinstance((yield o), bytes)
|
410
409
|
|
411
410
|
elif isinstance(o, self._Response):
|
412
411
|
i = None
|
413
412
|
r = self._preprocess_response(o)
|
414
413
|
b = self._build_response_bytes(r)
|
415
|
-
|
414
|
+
check.none((yield self.WriteIo(b)))
|
416
415
|
|
417
416
|
else:
|
418
417
|
raise TypeError(o)
|
@@ -435,7 +434,7 @@ class CoroHttpServer:
|
|
435
434
|
sz = next(gen)
|
436
435
|
while True:
|
437
436
|
try:
|
438
|
-
line =
|
437
|
+
line = check.isinstance((yield self.ReadLineIo(sz)), bytes)
|
439
438
|
sz = gen.send(line)
|
440
439
|
except StopIteration as e:
|
441
440
|
parsed = e.value
|
@@ -454,11 +453,11 @@ class CoroHttpServer:
|
|
454
453
|
yield self._build_error_response(err)
|
455
454
|
return
|
456
455
|
|
457
|
-
parsed =
|
456
|
+
parsed = check.isinstance(parsed, ParsedHttpRequest)
|
458
457
|
|
459
458
|
# Log
|
460
459
|
|
461
|
-
|
460
|
+
check.none((yield self.ParsedRequestLogIo(parsed)))
|
462
461
|
|
463
462
|
# Handle CONTINUE
|
464
463
|
|
@@ -474,7 +473,7 @@ class CoroHttpServer:
|
|
474
473
|
|
475
474
|
request_data: ta.Optional[bytes]
|
476
475
|
if (cl := parsed.headers.get('Content-Length')) is not None:
|
477
|
-
request_data =
|
476
|
+
request_data = check.isinstance((yield self.ReadIo(int(cl))), bytes)
|
478
477
|
else:
|
479
478
|
request_data = None
|
480
479
|
|
@@ -482,7 +481,7 @@ class CoroHttpServer:
|
|
482
481
|
|
483
482
|
handler_request = HttpHandlerRequest(
|
484
483
|
client_address=self._client_address,
|
485
|
-
method=
|
484
|
+
method=check.not_none(parsed.method),
|
486
485
|
path=parsed.path,
|
487
486
|
headers=parsed.headers,
|
488
487
|
data=request_data,
|
omlish/io/buffers.py
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
import io
|
4
4
|
import typing as ta
|
5
5
|
|
6
|
-
from ..lite.check import
|
7
|
-
from ..lite.check import check_not_empty
|
8
|
-
from ..lite.check import check_not_none
|
6
|
+
from ..lite.check import check
|
9
7
|
from ..lite.strings import attr_repr
|
10
8
|
|
11
9
|
|
@@ -40,7 +38,7 @@ class DelimitingBuffer:
|
|
40
38
|
) -> None:
|
41
39
|
super().__init__()
|
42
40
|
|
43
|
-
self._delimiters = frozenset(
|
41
|
+
self._delimiters = frozenset(check.isinstance(d, int) for d in delimiters)
|
44
42
|
self._keep_ends = keep_ends
|
45
43
|
self._max_size = max_size
|
46
44
|
|
@@ -71,7 +69,7 @@ class DelimitingBuffer:
|
|
71
69
|
return r
|
72
70
|
|
73
71
|
def _append_and_reset(self, chunk: bytes) -> bytes:
|
74
|
-
buf =
|
72
|
+
buf = check.not_none(self._buf)
|
75
73
|
if not buf.tell():
|
76
74
|
return chunk
|
77
75
|
|
@@ -193,7 +191,7 @@ class IncrementalWriteBuffer:
|
|
193
191
|
) -> None:
|
194
192
|
super().__init__()
|
195
193
|
|
196
|
-
|
194
|
+
check.not_empty(data)
|
197
195
|
self._len = len(data)
|
198
196
|
self._write_size = write_size
|
199
197
|
|
@@ -208,11 +206,11 @@ class IncrementalWriteBuffer:
|
|
208
206
|
return self._len - self._pos
|
209
207
|
|
210
208
|
def write(self, fn: ta.Callable[[bytes], int]) -> int:
|
211
|
-
lst =
|
209
|
+
lst = check.not_empty(self._lst)
|
212
210
|
|
213
211
|
t = 0
|
214
212
|
for i, d in enumerate(lst): # noqa
|
215
|
-
n = fn(
|
213
|
+
n = fn(check.not_empty(d))
|
216
214
|
if not n:
|
217
215
|
break
|
218
216
|
t += n
|
omlish/io/fdio/corohttp.py
CHANGED
@@ -2,12 +2,9 @@
|
|
2
2
|
import socket
|
3
3
|
import typing as ta
|
4
4
|
|
5
|
-
from ...
|
6
|
-
from ...
|
7
|
-
from ...lite.check import
|
8
|
-
from ...lite.check import check_state
|
9
|
-
from ...lite.http.coroserver import CoroHttpServer
|
10
|
-
from ...lite.http.handlers import HttpHandler
|
5
|
+
from ...http.coroserver import CoroHttpServer
|
6
|
+
from ...http.handlers import HttpHandler
|
7
|
+
from ...lite.check import check
|
11
8
|
from ...lite.socket import SocketAddress
|
12
9
|
from ..buffers import IncrementalWriteBuffer
|
13
10
|
from ..buffers import ReadableListBuffer
|
@@ -25,7 +22,7 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
|
|
25
22
|
write_size: int = 0x10000,
|
26
23
|
log_handler: ta.Optional[ta.Callable[[CoroHttpServer, CoroHttpServer.AnyLogIo], None]] = None,
|
27
24
|
) -> None:
|
28
|
-
|
25
|
+
check.state(not sock.getblocking())
|
29
26
|
|
30
27
|
super().__init__(addr, sock)
|
31
28
|
|
@@ -49,7 +46,7 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
|
|
49
46
|
#
|
50
47
|
|
51
48
|
def _next_io(self) -> None: # noqa
|
52
|
-
coro =
|
49
|
+
coro = check.not_none(self._srv_coro)
|
53
50
|
|
54
51
|
d: bytes | None = None
|
55
52
|
o = self._cur_io
|
@@ -82,7 +79,7 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
|
|
82
79
|
o = None
|
83
80
|
|
84
81
|
elif isinstance(o, CoroHttpServer.WriteIo):
|
85
|
-
|
82
|
+
check.none(self._write_buf)
|
86
83
|
self._write_buf = IncrementalWriteBuffer(o.data, write_size=self._write_size)
|
87
84
|
break
|
88
85
|
|
@@ -103,7 +100,7 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
|
|
103
100
|
|
104
101
|
def on_readable(self) -> None:
|
105
102
|
try:
|
106
|
-
buf =
|
103
|
+
buf = check.not_none(self._sock).recv(self._read_size)
|
107
104
|
except BlockingIOError:
|
108
105
|
return
|
109
106
|
except ConnectionResetError:
|
@@ -119,12 +116,12 @@ class CoroHttpServerConnectionFdioHandler(SocketFdioHandler):
|
|
119
116
|
self._next_io()
|
120
117
|
|
121
118
|
def on_writable(self) -> None:
|
122
|
-
|
123
|
-
wb =
|
119
|
+
check.isinstance(self._cur_io, CoroHttpServer.WriteIo)
|
120
|
+
wb = check.not_none(self._write_buf)
|
124
121
|
while wb.rem > 0:
|
125
122
|
def send(d: bytes) -> int:
|
126
123
|
try:
|
127
|
-
return
|
124
|
+
return check.not_none(self._sock).send(d)
|
128
125
|
except ConnectionResetError:
|
129
126
|
self.close()
|
130
127
|
return 0
|
omlish/io/fdio/handlers.py
CHANGED
@@ -3,7 +3,7 @@ import abc
|
|
3
3
|
import socket
|
4
4
|
import typing as ta
|
5
5
|
|
6
|
-
from ...lite.check import
|
6
|
+
from ...lite.check import check
|
7
7
|
from ...lite.socket import SocketAddress
|
8
8
|
|
9
9
|
|
@@ -55,7 +55,7 @@ class SocketFdioHandler(FdioHandler, abc.ABC):
|
|
55
55
|
self._sock: ta.Optional[socket.socket] = sock
|
56
56
|
|
57
57
|
def fd(self) -> int:
|
58
|
-
return
|
58
|
+
return check.not_none(self._sock).fileno()
|
59
59
|
|
60
60
|
@property
|
61
61
|
def closed(self) -> bool:
|
@@ -8,10 +8,7 @@ import subprocess
|
|
8
8
|
import sys
|
9
9
|
import typing as ta
|
10
10
|
|
11
|
-
from ..check import
|
12
|
-
from ..check import check_isinstance
|
13
|
-
from ..check import check_not_none
|
14
|
-
from ..check import check_single
|
11
|
+
from ..check import check
|
15
12
|
from ..logs import log
|
16
13
|
from ..subprocesses import DEFAULT_SUBPROCESS_TRY_EXCEPTIONS
|
17
14
|
from ..subprocesses import prepare_subprocess_invocation
|
@@ -36,7 +33,7 @@ async def asyncio_subprocess_popen(
|
|
36
33
|
if shell:
|
37
34
|
fac = functools.partial(
|
38
35
|
asyncio.create_subprocess_shell,
|
39
|
-
|
36
|
+
check.single(cmd),
|
40
37
|
)
|
41
38
|
else:
|
42
39
|
fac = functools.partial(
|
@@ -76,7 +73,7 @@ class AsyncioProcessCommunicator:
|
|
76
73
|
self._proc = proc
|
77
74
|
self._loop = loop
|
78
75
|
|
79
|
-
self._transport: asyncio.base_subprocess.BaseSubprocessTransport =
|
76
|
+
self._transport: asyncio.base_subprocess.BaseSubprocessTransport = check.isinstance(
|
80
77
|
proc._transport, # type: ignore # noqa
|
81
78
|
asyncio.base_subprocess.BaseSubprocessTransport,
|
82
79
|
)
|
@@ -86,7 +83,7 @@ class AsyncioProcessCommunicator:
|
|
86
83
|
return self._loop.get_debug()
|
87
84
|
|
88
85
|
async def _feed_stdin(self, input: bytes) -> None: # noqa
|
89
|
-
stdin =
|
86
|
+
stdin = check.not_none(self._proc.stdin)
|
90
87
|
try:
|
91
88
|
if input is not None:
|
92
89
|
stdin.write(input)
|
@@ -110,13 +107,13 @@ class AsyncioProcessCommunicator:
|
|
110
107
|
return None
|
111
108
|
|
112
109
|
async def _read_stream(self, fd: int) -> bytes:
|
113
|
-
transport: ta.Any =
|
110
|
+
transport: ta.Any = check.not_none(self._transport.get_pipe_transport(fd))
|
114
111
|
|
115
112
|
if fd == 2:
|
116
|
-
stream =
|
113
|
+
stream = check.not_none(self._proc.stderr)
|
117
114
|
else:
|
118
|
-
|
119
|
-
stream =
|
115
|
+
check.equal(fd, 1)
|
116
|
+
stream = check.not_none(self._proc.stdout)
|
120
117
|
|
121
118
|
if self._debug:
|
122
119
|
name = 'stdout' if fd == 1 else 'stderr'
|
@@ -236,7 +233,7 @@ async def asyncio_subprocess_check_output(
|
|
236
233
|
**kwargs,
|
237
234
|
)
|
238
235
|
|
239
|
-
return
|
236
|
+
return check.not_none(stdout)
|
240
237
|
|
241
238
|
|
242
239
|
async def asyncio_subprocess_check_output_str(*args: str, **kwargs: ta.Any) -> str:
|