omlish 0.0.0.dev133__py3-none-any.whl → 0.0.0.dev177__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/.manifests.json +265 -7
- omlish/__about__.py +5 -3
- omlish/antlr/_runtime/__init__.py +0 -22
- omlish/antlr/_runtime/_all.py +24 -0
- omlish/antlr/_runtime/atn/ParserATNSimulator.py +1 -1
- omlish/antlr/_runtime/dfa/DFASerializer.py +1 -1
- omlish/antlr/_runtime/error/DiagnosticErrorListener.py +2 -1
- omlish/antlr/_runtime/xpath/XPath.py +7 -1
- omlish/antlr/_runtime/xpath/XPathLexer.py +1 -1
- omlish/antlr/delimit.py +106 -0
- omlish/antlr/dot.py +31 -0
- omlish/antlr/errors.py +11 -0
- omlish/antlr/input.py +96 -0
- omlish/antlr/parsing.py +19 -0
- omlish/antlr/runtime.py +102 -0
- omlish/antlr/utils.py +38 -0
- omlish/argparse/all.py +45 -0
- omlish/{argparse.py → argparse/cli.py} +112 -107
- omlish/asyncs/__init__.py +0 -35
- omlish/asyncs/all.py +35 -0
- omlish/asyncs/asyncio/all.py +7 -0
- omlish/asyncs/asyncio/channels.py +40 -0
- omlish/asyncs/asyncio/streams.py +45 -0
- omlish/asyncs/asyncio/subprocesses.py +238 -0
- omlish/asyncs/asyncio/timeouts.py +16 -0
- omlish/asyncs/bluelet/LICENSE +6 -0
- omlish/asyncs/bluelet/all.py +67 -0
- omlish/asyncs/bluelet/api.py +23 -0
- omlish/asyncs/bluelet/core.py +178 -0
- omlish/asyncs/bluelet/events.py +78 -0
- omlish/asyncs/bluelet/files.py +80 -0
- omlish/asyncs/bluelet/runner.py +416 -0
- omlish/asyncs/bluelet/sockets.py +214 -0
- omlish/bootstrap/sys.py +3 -3
- omlish/cached.py +2 -2
- omlish/check.py +49 -460
- omlish/codecs/__init__.py +72 -0
- omlish/codecs/base.py +106 -0
- omlish/codecs/bytes.py +119 -0
- omlish/codecs/chain.py +23 -0
- omlish/codecs/funcs.py +39 -0
- omlish/codecs/registry.py +139 -0
- omlish/codecs/standard.py +4 -0
- omlish/codecs/text.py +217 -0
- omlish/collections/cache/impl.py +50 -57
- omlish/collections/coerce.py +1 -0
- omlish/collections/mappings.py +1 -1
- omlish/configs/flattening.py +1 -1
- omlish/defs.py +1 -1
- omlish/diag/_pycharm/runhack.py +8 -2
- omlish/diag/procfs.py +8 -8
- omlish/docker/__init__.py +0 -36
- omlish/docker/all.py +31 -0
- omlish/docker/consts.py +4 -0
- omlish/{lite/docker.py → docker/detect.py} +18 -0
- omlish/docker/{helpers.py → timebomb.py} +0 -21
- omlish/formats/cbor.py +31 -0
- omlish/formats/cloudpickle.py +31 -0
- omlish/formats/codecs.py +93 -0
- omlish/formats/json/codecs.py +29 -0
- omlish/formats/json/delimted.py +4 -0
- omlish/formats/json/stream/errors.py +2 -0
- omlish/formats/json/stream/lex.py +12 -6
- omlish/formats/json/stream/parse.py +38 -22
- omlish/formats/json5.py +31 -0
- omlish/formats/pickle.py +31 -0
- omlish/formats/repr.py +25 -0
- omlish/formats/toml.py +17 -0
- omlish/formats/yaml.py +25 -0
- omlish/funcs/__init__.py +0 -0
- omlish/{genmachine.py → funcs/genmachine.py} +5 -4
- omlish/{matchfns.py → funcs/match.py} +1 -1
- omlish/funcs/pairs.py +215 -0
- omlish/http/__init__.py +0 -48
- omlish/http/all.py +48 -0
- omlish/http/coro/__init__.py +0 -0
- omlish/{lite/fdio/corohttp.py → http/coro/fdio.py} +21 -19
- omlish/{lite/http/coroserver.py → http/coro/server.py} +20 -21
- omlish/{lite/http → http}/handlers.py +3 -2
- omlish/{lite/http → http}/parsing.py +1 -0
- omlish/http/sessions.py +1 -1
- omlish/{lite/http → http}/versions.py +1 -0
- omlish/inject/managed.py +2 -2
- omlish/io/__init__.py +0 -3
- omlish/{lite/io.py → io/buffers.py} +8 -9
- omlish/io/compress/__init__.py +9 -0
- omlish/io/compress/abc.py +104 -0
- omlish/io/compress/adapters.py +148 -0
- omlish/io/compress/base.py +24 -0
- omlish/io/compress/brotli.py +47 -0
- omlish/io/compress/bz2.py +61 -0
- omlish/io/compress/codecs.py +78 -0
- omlish/io/compress/gzip.py +350 -0
- omlish/io/compress/lz4.py +91 -0
- omlish/io/compress/lzma.py +81 -0
- omlish/io/compress/snappy.py +34 -0
- omlish/io/compress/zlib.py +74 -0
- omlish/io/compress/zstd.py +44 -0
- omlish/io/fdio/__init__.py +1 -0
- omlish/{lite → io}/fdio/handlers.py +5 -5
- omlish/{lite → io}/fdio/kqueue.py +8 -8
- omlish/{lite → io}/fdio/manager.py +7 -7
- omlish/{lite → io}/fdio/pollers.py +13 -13
- omlish/io/generators/__init__.py +56 -0
- omlish/io/generators/consts.py +1 -0
- omlish/io/generators/direct.py +13 -0
- omlish/io/generators/readers.py +189 -0
- omlish/io/generators/stepped.py +191 -0
- omlish/io/pyio.py +5 -2
- omlish/iterators/__init__.py +24 -0
- omlish/iterators/iterators.py +132 -0
- omlish/iterators/recipes.py +18 -0
- omlish/iterators/tools.py +96 -0
- omlish/iterators/unique.py +67 -0
- omlish/lang/__init__.py +13 -1
- omlish/lang/functions.py +11 -2
- omlish/lang/generators.py +243 -0
- omlish/lang/iterables.py +46 -49
- omlish/lang/maybes.py +4 -4
- omlish/lite/cached.py +39 -6
- omlish/lite/check.py +438 -75
- omlish/lite/contextmanagers.py +17 -4
- omlish/lite/dataclasses.py +42 -0
- omlish/lite/inject.py +28 -45
- omlish/lite/logs.py +0 -270
- omlish/lite/marshal.py +309 -144
- omlish/lite/pycharm.py +47 -0
- omlish/lite/reflect.py +33 -0
- omlish/lite/resources.py +8 -0
- omlish/lite/runtime.py +4 -4
- omlish/lite/shlex.py +12 -0
- omlish/lite/socketserver.py +2 -2
- omlish/lite/strings.py +31 -0
- omlish/logs/__init__.py +0 -32
- omlish/logs/{_abc.py → abc.py} +0 -1
- omlish/logs/all.py +37 -0
- omlish/logs/{formatters.py → color.py} +1 -2
- omlish/logs/configs.py +7 -38
- omlish/logs/filters.py +10 -0
- omlish/logs/handlers.py +4 -1
- omlish/logs/json.py +56 -0
- omlish/logs/proxy.py +99 -0
- omlish/logs/standard.py +128 -0
- omlish/logs/utils.py +2 -2
- omlish/manifests/__init__.py +2 -0
- omlish/manifests/load.py +209 -0
- omlish/manifests/types.py +17 -0
- omlish/marshal/base.py +1 -1
- omlish/marshal/factories.py +1 -1
- omlish/marshal/forbidden.py +1 -1
- omlish/marshal/iterables.py +1 -1
- omlish/marshal/literals.py +50 -0
- omlish/marshal/mappings.py +1 -1
- omlish/marshal/maybes.py +1 -1
- omlish/marshal/standard.py +5 -1
- omlish/marshal/unions.py +1 -1
- omlish/os/__init__.py +0 -0
- omlish/os/atomics.py +205 -0
- omlish/os/deathsig.py +23 -0
- omlish/{os.py → os/files.py} +0 -9
- omlish/{lite → os}/journald.py +2 -1
- omlish/os/linux.py +484 -0
- omlish/os/paths.py +36 -0
- omlish/{lite → os}/pidfile.py +1 -0
- omlish/os/sizes.py +9 -0
- omlish/reflect/__init__.py +3 -0
- omlish/reflect/subst.py +2 -1
- omlish/reflect/types.py +126 -44
- omlish/secrets/pwhash.py +1 -1
- omlish/secrets/subprocesses.py +3 -1
- omlish/specs/jsonrpc/marshal.py +1 -1
- omlish/specs/openapi/marshal.py +1 -1
- omlish/sql/alchemy/asyncs.py +1 -1
- omlish/sql/queries/__init__.py +9 -1
- omlish/sql/queries/building.py +3 -0
- omlish/sql/queries/exprs.py +10 -27
- omlish/sql/queries/idents.py +48 -10
- omlish/sql/queries/names.py +80 -13
- omlish/sql/queries/params.py +64 -0
- omlish/sql/queries/rendering.py +1 -1
- omlish/subprocesses.py +340 -0
- omlish/term.py +29 -14
- omlish/testing/pytest/marks.py +2 -2
- omlish/testing/pytest/plugins/asyncs.py +6 -1
- omlish/testing/pytest/plugins/logging.py +1 -1
- omlish/testing/pytest/plugins/switches.py +1 -1
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/METADATA +7 -5
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/RECORD +200 -117
- omlish/fnpairs.py +0 -496
- omlish/formats/json/cli/__main__.py +0 -11
- omlish/formats/json/cli/cli.py +0 -298
- omlish/formats/json/cli/formats.py +0 -71
- omlish/formats/json/cli/io.py +0 -74
- omlish/formats/json/cli/parsing.py +0 -82
- omlish/formats/json/cli/processing.py +0 -48
- omlish/formats/json/cli/rendering.py +0 -92
- omlish/iterators.py +0 -300
- omlish/lite/subprocesses.py +0 -130
- /omlish/{formats/json/cli → argparse}/__init__.py +0 -0
- /omlish/{lite/fdio → asyncs/asyncio}/__init__.py +0 -0
- /omlish/asyncs/{asyncio.py → asyncio/asyncio.py} +0 -0
- /omlish/{lite/http → asyncs/bluelet}/__init__.py +0 -0
- /omlish/collections/{_abc.py → abc.py} +0 -0
- /omlish/{fnpipes.py → funcs/pipes.py} +0 -0
- /omlish/io/{_abc.py → abc.py} +0 -0
- /omlish/sql/{_abc.py → abc.py} +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev133.dist-info → omlish-0.0.0.dev177.dist-info}/top_level.txt +0 -0
omlish/iterators.py
DELETED
@@ -1,300 +0,0 @@
|
|
1
|
-
import collections
|
2
|
-
import dataclasses as dc
|
3
|
-
import functools
|
4
|
-
import heapq
|
5
|
-
import itertools
|
6
|
-
import typing as ta
|
7
|
-
|
8
|
-
# from . import check
|
9
|
-
from . import lang
|
10
|
-
|
11
|
-
|
12
|
-
T = ta.TypeVar('T')
|
13
|
-
U = ta.TypeVar('U')
|
14
|
-
|
15
|
-
_MISSING = object()
|
16
|
-
|
17
|
-
|
18
|
-
class PeekIterator(ta.Iterator[T]):
|
19
|
-
|
20
|
-
def __init__(self, it: ta.Iterable[T]) -> None:
|
21
|
-
super().__init__()
|
22
|
-
|
23
|
-
self._it = iter(it)
|
24
|
-
self._pos = -1
|
25
|
-
self._next_item: ta.Any = _MISSING
|
26
|
-
|
27
|
-
_item: T
|
28
|
-
|
29
|
-
def __iter__(self) -> ta.Self:
|
30
|
-
return self
|
31
|
-
|
32
|
-
@property
|
33
|
-
def done(self) -> bool:
|
34
|
-
try:
|
35
|
-
self.peek()
|
36
|
-
except StopIteration:
|
37
|
-
return True
|
38
|
-
else:
|
39
|
-
return False
|
40
|
-
|
41
|
-
def __next__(self) -> T:
|
42
|
-
if self._next_item is not _MISSING:
|
43
|
-
self._item = ta.cast(T, self._next_item)
|
44
|
-
self._next_item = _MISSING
|
45
|
-
else:
|
46
|
-
self._item = next(self._it)
|
47
|
-
self._pos += 1
|
48
|
-
return self._item
|
49
|
-
|
50
|
-
def peek(self) -> T:
|
51
|
-
if self._next_item is not _MISSING:
|
52
|
-
return ta.cast(T, self._next_item)
|
53
|
-
self._next_item = next(self._it)
|
54
|
-
return self._next_item
|
55
|
-
|
56
|
-
def next_peek(self) -> T:
|
57
|
-
next(self)
|
58
|
-
return self.peek()
|
59
|
-
|
60
|
-
def takewhile(self, fn: ta.Callable[[T], bool]) -> ta.Iterator[T]:
|
61
|
-
while fn(self.peek()):
|
62
|
-
yield next(self)
|
63
|
-
|
64
|
-
def skipwhile(self, fn: ta.Callable[[T], bool]) -> None:
|
65
|
-
while fn(self.peek()):
|
66
|
-
next(self)
|
67
|
-
|
68
|
-
def takeuntil(self, fn: ta.Callable[[T], bool]) -> ta.Iterator[T]:
|
69
|
-
return self.takewhile(lambda e: not fn(e))
|
70
|
-
|
71
|
-
def skipuntil(self, fn: ta.Callable[[T], bool]) -> None:
|
72
|
-
self.skipwhile(lambda e: not fn(e))
|
73
|
-
|
74
|
-
def takethrough(self, pos: int) -> ta.Iterator[T]:
|
75
|
-
return self.takewhile(lambda _: self._pos < pos)
|
76
|
-
|
77
|
-
def skipthrough(self, pos: int) -> None:
|
78
|
-
self.skipwhile(lambda _: self._pos < pos)
|
79
|
-
|
80
|
-
def taketo(self, pos: int) -> ta.Iterator[T]:
|
81
|
-
return self.takethrough(pos - 1)
|
82
|
-
|
83
|
-
def skipto(self, pos: int) -> None:
|
84
|
-
self.skipthrough(pos - 1)
|
85
|
-
|
86
|
-
|
87
|
-
class ProxyIterator(ta.Iterator[T]):
|
88
|
-
|
89
|
-
def __init__(self, fn: ta.Callable[[], T]) -> None:
|
90
|
-
self._fn = fn
|
91
|
-
|
92
|
-
def __iter__(self) -> ta.Self:
|
93
|
-
return self
|
94
|
-
|
95
|
-
def __next__(self) -> T:
|
96
|
-
return self._fn()
|
97
|
-
|
98
|
-
|
99
|
-
class PrefetchIterator(ta.Iterator[T]):
|
100
|
-
|
101
|
-
def __init__(self, fn: ta.Callable[[], T] | None = None) -> None:
|
102
|
-
super().__init__()
|
103
|
-
|
104
|
-
self._fn = fn
|
105
|
-
self._deque: collections.deque[T] = collections.deque()
|
106
|
-
|
107
|
-
def __iter__(self) -> ta.Self:
|
108
|
-
return self
|
109
|
-
|
110
|
-
def push(self, item) -> None:
|
111
|
-
self._deque.append(item)
|
112
|
-
|
113
|
-
def __next__(self) -> T:
|
114
|
-
try:
|
115
|
-
return self._deque.popleft()
|
116
|
-
except IndexError:
|
117
|
-
if self._fn is None:
|
118
|
-
raise StopIteration from None
|
119
|
-
return self._fn()
|
120
|
-
|
121
|
-
|
122
|
-
class RetainIterator(ta.Iterator[T]):
|
123
|
-
|
124
|
-
def __init__(self, fn: ta.Callable[[], T]) -> None:
|
125
|
-
super().__init__()
|
126
|
-
|
127
|
-
self._fn = fn
|
128
|
-
self._deque: collections.deque[T] = collections.deque()
|
129
|
-
|
130
|
-
def __iter__(self) -> ta.Self:
|
131
|
-
return self
|
132
|
-
|
133
|
-
def pop(self) -> None:
|
134
|
-
self._deque.popleft()
|
135
|
-
|
136
|
-
def __next__(self) -> T:
|
137
|
-
item = self._fn()
|
138
|
-
self._deque.append(item)
|
139
|
-
return item
|
140
|
-
|
141
|
-
|
142
|
-
def unzip(it: ta.Iterable[T], width: int | None = None) -> list:
|
143
|
-
if width is None:
|
144
|
-
if not isinstance(it, PeekIterator):
|
145
|
-
it = PeekIterator(iter(it))
|
146
|
-
try:
|
147
|
-
width = len(it.peek())
|
148
|
-
except StopIteration:
|
149
|
-
return []
|
150
|
-
|
151
|
-
its: list[PrefetchIterator[T]] = []
|
152
|
-
running = True
|
153
|
-
|
154
|
-
def next_fn(idx):
|
155
|
-
nonlocal running
|
156
|
-
if not running:
|
157
|
-
raise StopIteration
|
158
|
-
try:
|
159
|
-
items = next(it) # type: ignore
|
160
|
-
except StopIteration:
|
161
|
-
running = False
|
162
|
-
raise
|
163
|
-
for item_idx, item in enumerate(items):
|
164
|
-
its[item_idx].push(item)
|
165
|
-
return next(its[idx])
|
166
|
-
|
167
|
-
its.extend(PrefetchIterator(functools.partial(next_fn, idx)) for idx in range(width))
|
168
|
-
return its
|
169
|
-
|
170
|
-
|
171
|
-
def take(n: int, iterable: ta.Iterable[T]) -> list[T]:
|
172
|
-
return list(itertools.islice(iterable, n))
|
173
|
-
|
174
|
-
|
175
|
-
def chunk(n: int, iterable: ta.Iterable[T], strict: bool = False) -> ta.Iterator[list[T]]:
|
176
|
-
iterator = iter(functools.partial(take, n, iter(iterable)), [])
|
177
|
-
if strict:
|
178
|
-
def ret():
|
179
|
-
for chunk in iterator:
|
180
|
-
if len(chunk) != n:
|
181
|
-
raise ValueError('iterable is not divisible by n.')
|
182
|
-
yield chunk
|
183
|
-
return iter(ret())
|
184
|
-
else:
|
185
|
-
return iterator
|
186
|
-
|
187
|
-
|
188
|
-
def merge_on(
|
189
|
-
function: ta.Callable[[T], U],
|
190
|
-
*its: ta.Iterable[T],
|
191
|
-
) -> ta.Iterator[tuple[U, list[tuple[int, T]]]]:
|
192
|
-
indexed_its = [
|
193
|
-
(
|
194
|
-
(function(item), it_idx, item)
|
195
|
-
for it_idx, item in zip(itertools.repeat(it_idx), it)
|
196
|
-
)
|
197
|
-
for it_idx, it in enumerate(its)
|
198
|
-
]
|
199
|
-
|
200
|
-
grouped_indexed_its = itertools.groupby(
|
201
|
-
heapq.merge(*indexed_its),
|
202
|
-
key=lambda item_tuple: item_tuple[0],
|
203
|
-
)
|
204
|
-
|
205
|
-
return (
|
206
|
-
(fn_item, [(it_idx, item) for _, it_idx, item in grp])
|
207
|
-
for fn_item, grp in grouped_indexed_its
|
208
|
-
)
|
209
|
-
|
210
|
-
|
211
|
-
def expand_indexed_pairs(
|
212
|
-
seq: ta.Iterable[tuple[int, T]],
|
213
|
-
default: T,
|
214
|
-
*,
|
215
|
-
width: int | None = None,
|
216
|
-
) -> list[T]:
|
217
|
-
width_ = width
|
218
|
-
if width_ is None:
|
219
|
-
width_ = (max(idx for idx, _ in seq) + 1) if seq else 0
|
220
|
-
result = [default] * width_
|
221
|
-
for idx, value in seq:
|
222
|
-
if idx < width_:
|
223
|
-
result[idx] = value
|
224
|
-
return result
|
225
|
-
|
226
|
-
|
227
|
-
##
|
228
|
-
# https://docs.python.org/3/library/itertools.html#itertools-recipes
|
229
|
-
|
230
|
-
|
231
|
-
def sliding_window(it: ta.Iterable[T], n: int) -> ta.Iterator[tuple[T, ...]]:
|
232
|
-
# sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG
|
233
|
-
iterator = iter(it)
|
234
|
-
window = collections.deque(itertools.islice(iterator, n - 1), maxlen=n)
|
235
|
-
for x in iterator:
|
236
|
-
window.append(x)
|
237
|
-
yield tuple(window)
|
238
|
-
|
239
|
-
|
240
|
-
##
|
241
|
-
|
242
|
-
|
243
|
-
@dc.dataclass()
|
244
|
-
class UniqueStats:
|
245
|
-
key: ta.Any
|
246
|
-
num_seen: int
|
247
|
-
first_idx: int
|
248
|
-
last_idx: int
|
249
|
-
|
250
|
-
|
251
|
-
@dc.dataclass(frozen=True)
|
252
|
-
class UniqueItem(ta.Generic[T]):
|
253
|
-
idx: int
|
254
|
-
item: T
|
255
|
-
stats: UniqueStats
|
256
|
-
out: lang.Maybe[T]
|
257
|
-
|
258
|
-
|
259
|
-
class UniqueIterator(ta.Iterator[UniqueItem[T]]):
|
260
|
-
def __init__(
|
261
|
-
self,
|
262
|
-
it: ta.Iterable[T],
|
263
|
-
keyer: ta.Callable[[T], ta.Any] = lang.identity,
|
264
|
-
) -> None:
|
265
|
-
super().__init__()
|
266
|
-
self._it = enumerate(it)
|
267
|
-
self._keyer = keyer
|
268
|
-
|
269
|
-
self.stats: dict[ta.Any, UniqueStats] = {}
|
270
|
-
|
271
|
-
def __next__(self) -> UniqueItem[T]:
|
272
|
-
idx, item = next(self._it)
|
273
|
-
key = self._keyer(item)
|
274
|
-
|
275
|
-
try:
|
276
|
-
stats = self.stats[key]
|
277
|
-
|
278
|
-
except KeyError:
|
279
|
-
stats = self.stats[key] = UniqueStats(
|
280
|
-
key,
|
281
|
-
num_seen=1,
|
282
|
-
first_idx=idx,
|
283
|
-
last_idx=idx,
|
284
|
-
)
|
285
|
-
return UniqueItem(
|
286
|
-
idx,
|
287
|
-
item,
|
288
|
-
stats,
|
289
|
-
lang.just(item),
|
290
|
-
)
|
291
|
-
|
292
|
-
else:
|
293
|
-
stats.num_seen += 1
|
294
|
-
stats.last_idx = idx
|
295
|
-
return UniqueItem(
|
296
|
-
idx,
|
297
|
-
item,
|
298
|
-
stats,
|
299
|
-
lang.empty(),
|
300
|
-
)
|
omlish/lite/subprocesses.py
DELETED
@@ -1,130 +0,0 @@
|
|
1
|
-
# ruff: noqa: UP006 UP007
|
2
|
-
import logging
|
3
|
-
import os
|
4
|
-
import shlex
|
5
|
-
import subprocess
|
6
|
-
import sys
|
7
|
-
import typing as ta
|
8
|
-
|
9
|
-
from .logs import log
|
10
|
-
from .runtime import is_debugger_attached
|
11
|
-
|
12
|
-
|
13
|
-
##
|
14
|
-
|
15
|
-
|
16
|
-
_SUBPROCESS_SHELL_WRAP_EXECS = False
|
17
|
-
|
18
|
-
|
19
|
-
def subprocess_shell_wrap_exec(*args: str) -> ta.Tuple[str, ...]:
|
20
|
-
return ('sh', '-c', ' '.join(map(shlex.quote, args)))
|
21
|
-
|
22
|
-
|
23
|
-
def subprocess_maybe_shell_wrap_exec(*args: str) -> ta.Tuple[str, ...]:
|
24
|
-
if _SUBPROCESS_SHELL_WRAP_EXECS or is_debugger_attached():
|
25
|
-
return subprocess_shell_wrap_exec(*args)
|
26
|
-
else:
|
27
|
-
return args
|
28
|
-
|
29
|
-
|
30
|
-
def _prepare_subprocess_invocation(
|
31
|
-
*args: str,
|
32
|
-
env: ta.Optional[ta.Mapping[str, ta.Any]] = None,
|
33
|
-
extra_env: ta.Optional[ta.Mapping[str, ta.Any]] = None,
|
34
|
-
quiet: bool = False,
|
35
|
-
shell: bool = False,
|
36
|
-
**kwargs: ta.Any,
|
37
|
-
) -> ta.Tuple[ta.Tuple[ta.Any, ...], ta.Dict[str, ta.Any]]:
|
38
|
-
log.debug(args)
|
39
|
-
if extra_env:
|
40
|
-
log.debug(extra_env)
|
41
|
-
|
42
|
-
if extra_env:
|
43
|
-
env = {**(env if env is not None else os.environ), **extra_env}
|
44
|
-
|
45
|
-
if quiet and 'stderr' not in kwargs:
|
46
|
-
if not log.isEnabledFor(logging.DEBUG):
|
47
|
-
kwargs['stderr'] = subprocess.DEVNULL
|
48
|
-
|
49
|
-
if not shell:
|
50
|
-
args = subprocess_maybe_shell_wrap_exec(*args)
|
51
|
-
|
52
|
-
return args, dict(
|
53
|
-
env=env,
|
54
|
-
shell=shell,
|
55
|
-
**kwargs,
|
56
|
-
)
|
57
|
-
|
58
|
-
|
59
|
-
def subprocess_check_call(*args: str, stdout=sys.stderr, **kwargs: ta.Any) -> None:
|
60
|
-
args, kwargs = _prepare_subprocess_invocation(*args, stdout=stdout, **kwargs)
|
61
|
-
return subprocess.check_call(args, **kwargs) # type: ignore
|
62
|
-
|
63
|
-
|
64
|
-
def subprocess_check_output(*args: str, **kwargs: ta.Any) -> bytes:
|
65
|
-
args, kwargs = _prepare_subprocess_invocation(*args, **kwargs)
|
66
|
-
return subprocess.check_output(args, **kwargs)
|
67
|
-
|
68
|
-
|
69
|
-
def subprocess_check_output_str(*args: str, **kwargs: ta.Any) -> str:
|
70
|
-
return subprocess_check_output(*args, **kwargs).decode().strip()
|
71
|
-
|
72
|
-
|
73
|
-
##
|
74
|
-
|
75
|
-
|
76
|
-
DEFAULT_SUBPROCESS_TRY_EXCEPTIONS: ta.Tuple[ta.Type[Exception], ...] = (
|
77
|
-
FileNotFoundError,
|
78
|
-
subprocess.CalledProcessError,
|
79
|
-
)
|
80
|
-
|
81
|
-
|
82
|
-
def subprocess_try_call(
|
83
|
-
*args: str,
|
84
|
-
try_exceptions: ta.Tuple[ta.Type[Exception], ...] = DEFAULT_SUBPROCESS_TRY_EXCEPTIONS,
|
85
|
-
**kwargs: ta.Any,
|
86
|
-
) -> bool:
|
87
|
-
try:
|
88
|
-
subprocess_check_call(*args, **kwargs)
|
89
|
-
except try_exceptions as e: # noqa
|
90
|
-
if log.isEnabledFor(logging.DEBUG):
|
91
|
-
log.exception('command failed')
|
92
|
-
return False
|
93
|
-
else:
|
94
|
-
return True
|
95
|
-
|
96
|
-
|
97
|
-
def subprocess_try_output(
|
98
|
-
*args: str,
|
99
|
-
try_exceptions: ta.Tuple[ta.Type[Exception], ...] = DEFAULT_SUBPROCESS_TRY_EXCEPTIONS,
|
100
|
-
**kwargs: ta.Any,
|
101
|
-
) -> ta.Optional[bytes]:
|
102
|
-
try:
|
103
|
-
return subprocess_check_output(*args, **kwargs)
|
104
|
-
except try_exceptions as e: # noqa
|
105
|
-
if log.isEnabledFor(logging.DEBUG):
|
106
|
-
log.exception('command failed')
|
107
|
-
return None
|
108
|
-
|
109
|
-
|
110
|
-
def subprocess_try_output_str(*args: str, **kwargs: ta.Any) -> ta.Optional[str]:
|
111
|
-
out = subprocess_try_output(*args, **kwargs)
|
112
|
-
return out.decode().strip() if out is not None else None
|
113
|
-
|
114
|
-
|
115
|
-
##
|
116
|
-
|
117
|
-
|
118
|
-
def subprocess_close(
|
119
|
-
proc: subprocess.Popen,
|
120
|
-
timeout: ta.Optional[float] = None,
|
121
|
-
) -> None:
|
122
|
-
# TODO: terminate, sleep, kill
|
123
|
-
if proc.stdout:
|
124
|
-
proc.stdout.close()
|
125
|
-
if proc.stderr:
|
126
|
-
proc.stderr.close()
|
127
|
-
if proc.stdin:
|
128
|
-
proc.stdin.close()
|
129
|
-
|
130
|
-
proc.wait(timeout)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
/omlish/io/{_abc.py → abc.py}
RENAMED
File without changes
|
/omlish/sql/{_abc.py → abc.py}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|