omlish 0.0.0.dev141__py3-none-any.whl → 0.0.0.dev143__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 +4 -2
- omlish/check.py +2 -0
- omlish/collections/coerce.py +1 -0
- omlish/docker/__init__.py +2 -1
- omlish/docker/helpers.py +0 -6
- omlish/funcs/pairs.py +2 -2
- omlish/io/compress/__init__.py +9 -0
- omlish/io/compress/abc.py +4 -4
- omlish/io/compress/adapters.py +12 -11
- omlish/io/compress/base.py +24 -0
- omlish/io/compress/brotli.py +33 -0
- omlish/io/compress/bz2.py +26 -21
- omlish/io/compress/gzip.py +43 -10
- omlish/io/compress/lz4.py +77 -0
- omlish/io/compress/lzma.py +51 -16
- omlish/io/compress/snappy.py +20 -0
- omlish/io/compress/zlib.py +60 -0
- omlish/io/compress/zstd.py +30 -0
- omlish/io/generators/__init__.py +53 -0
- omlish/io/generators/consts.py +1 -0
- omlish/io/generators/direct.py +13 -0
- omlish/io/generators/readers.py +15 -9
- omlish/io/generators/stepped.py +85 -14
- omlish/io/pyio.py +5 -2
- omlish/lang/__init__.py +1 -0
- omlish/lang/iterables.py +20 -0
- omlish/lite/docker.py +3 -0
- omlish/lite/marshal.py +213 -141
- omlish/lite/pycharm.py +48 -0
- omlish/lite/subprocesses.py +13 -0
- omlish/logs/abc.py +0 -1
- {omlish-0.0.0.dev141.dist-info → omlish-0.0.0.dev143.dist-info}/METADATA +3 -1
- {omlish-0.0.0.dev141.dist-info → omlish-0.0.0.dev143.dist-info}/RECORD +37 -29
- omlish/io/compress/types.py +0 -29
- {omlish-0.0.0.dev141.dist-info → omlish-0.0.0.dev143.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev141.dist-info → omlish-0.0.0.dev143.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev141.dist-info → omlish-0.0.0.dev143.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev141.dist-info → omlish-0.0.0.dev143.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
import dataclasses as dc
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from ... import lang
|
5
|
+
from .base import Compression
|
6
|
+
|
7
|
+
|
8
|
+
if ta.TYPE_CHECKING:
|
9
|
+
import zstandard
|
10
|
+
else:
|
11
|
+
zstandard = lang.proxy_import('zstandard')
|
12
|
+
|
13
|
+
|
14
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
15
|
+
class ZstdCompression(Compression):
|
16
|
+
level: int | None = None
|
17
|
+
|
18
|
+
max_output_size: int = 0
|
19
|
+
|
20
|
+
def compress(self, d: bytes) -> bytes:
|
21
|
+
return zstandard.compress(
|
22
|
+
d,
|
23
|
+
**(dict(level=self.level) if self.level is not None else {}),
|
24
|
+
)
|
25
|
+
|
26
|
+
def decompress(self, d: bytes) -> bytes:
|
27
|
+
return zstandard.decompress(
|
28
|
+
d,
|
29
|
+
max_output_size=self.max_output_size,
|
30
|
+
)
|
omlish/io/generators/__init__.py
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
from .consts import ( # noqa
|
2
|
+
DEFAULT_BUFFER_SIZE,
|
3
|
+
)
|
4
|
+
|
5
|
+
from .direct import ( # noqa
|
6
|
+
DirectGenerator,
|
7
|
+
|
8
|
+
BytesDirectGenerator,
|
9
|
+
StrDirectGenerator,
|
10
|
+
)
|
11
|
+
|
12
|
+
from .readers import ( # noqa
|
13
|
+
ReaderGenerator,
|
14
|
+
BytesReaderGenerator,
|
15
|
+
StrReaderGenerator,
|
16
|
+
|
17
|
+
ExactReaderGenerator,
|
18
|
+
BytesExactReaderGenerator,
|
19
|
+
StrExactReaderGenerator,
|
20
|
+
|
21
|
+
GeneratorReader,
|
22
|
+
|
23
|
+
PrependableGeneratorReader,
|
24
|
+
PrependableBytesGeneratorReader,
|
25
|
+
PrependableStrGeneratorReader,
|
26
|
+
prependable_bytes_generator_reader,
|
27
|
+
prependable_str_generator_reader,
|
28
|
+
|
29
|
+
BufferedGeneratorReader,
|
30
|
+
BufferedBytesGeneratorReader,
|
31
|
+
BufferedStrGeneratorReader,
|
32
|
+
buffered_bytes_generator_reader,
|
33
|
+
buffered_str_generator_reader,
|
34
|
+
)
|
35
|
+
|
36
|
+
from .stepped import ( # noqa
|
37
|
+
SteppedGenerator,
|
38
|
+
BytesSteppedGenerator,
|
39
|
+
StrSteppedGenerator,
|
40
|
+
BytesToStrSteppedGenerator,
|
41
|
+
StrToBytesSteppedGenerator,
|
42
|
+
|
43
|
+
SteppedReaderGenerator,
|
44
|
+
BytesSteppedReaderGenerator,
|
45
|
+
StrSteppedReaderGenerator,
|
46
|
+
|
47
|
+
flatmap_stepped_generator,
|
48
|
+
|
49
|
+
joined_bytes_stepped_generator,
|
50
|
+
joined_str_stepped_generator,
|
51
|
+
|
52
|
+
read_into_bytes_stepped_generator,
|
53
|
+
)
|
@@ -0,0 +1 @@
|
|
1
|
+
DEFAULT_BUFFER_SIZE = 4 * 0x1000
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
|
4
|
+
O = ta.TypeVar('O')
|
5
|
+
I = ta.TypeVar('I')
|
6
|
+
R = ta.TypeVar('R')
|
7
|
+
|
8
|
+
|
9
|
+
# Direct generators yield outputs 1:1 with inputs.
|
10
|
+
DirectGenerator: ta.TypeAlias = ta.Generator[O, I, R]
|
11
|
+
|
12
|
+
BytesDirectGenerator: ta.TypeAlias = DirectGenerator[bytes, bytes, R]
|
13
|
+
StrDirectGenerator: ta.TypeAlias = DirectGenerator[str, str, R]
|
omlish/io/generators/readers.py
CHANGED
@@ -8,21 +8,29 @@ import abc
|
|
8
8
|
import typing as ta
|
9
9
|
|
10
10
|
from ... import check
|
11
|
+
from .consts import DEFAULT_BUFFER_SIZE
|
11
12
|
|
12
13
|
|
13
14
|
T = ta.TypeVar('T')
|
15
|
+
|
16
|
+
O = ta.TypeVar('O')
|
14
17
|
I = ta.TypeVar('I')
|
15
18
|
R = ta.TypeVar('R')
|
19
|
+
|
16
20
|
AnyT = ta.TypeVar('AnyT', bound=ta.Any)
|
17
21
|
|
18
22
|
|
23
|
+
# Reader generators yield ints of amounts of data needed, or None for needing any amount of data.
|
19
24
|
ReaderGenerator: ta.TypeAlias = ta.Generator[int | None, I, R]
|
20
|
-
ExactReaderGenerator: ta.TypeAlias = ta.Generator[int, I, R]
|
21
25
|
|
22
26
|
BytesReaderGenerator: ta.TypeAlias = ReaderGenerator[bytes, R]
|
23
|
-
BytesExactReaderGenerator: ta.TypeAlias = ExactReaderGenerator[bytes, R]
|
24
|
-
|
25
27
|
StrReaderGenerator: ta.TypeAlias = ReaderGenerator[str, R]
|
28
|
+
|
29
|
+
|
30
|
+
# Exact reader generators always specify read sizes.
|
31
|
+
ExactReaderGenerator: ta.TypeAlias = ta.Generator[int, I, R]
|
32
|
+
|
33
|
+
BytesExactReaderGenerator: ta.TypeAlias = ExactReaderGenerator[bytes, R]
|
26
34
|
StrExactReaderGenerator: ta.TypeAlias = ExactReaderGenerator[str, R]
|
27
35
|
|
28
36
|
|
@@ -44,10 +52,10 @@ class _StrJoiner:
|
|
44
52
|
|
45
53
|
class GeneratorReader(abc.ABC, ta.Generic[T]):
|
46
54
|
@abc.abstractmethod
|
47
|
-
def read(self, sz: int | None) ->
|
55
|
+
def read(self, sz: int | None) -> ReaderGenerator[T, T]:
|
48
56
|
raise NotImplementedError
|
49
57
|
|
50
|
-
def read_exact(self, sz: int) ->
|
58
|
+
def read_exact(self, sz: int) -> ReaderGenerator[T, T]:
|
51
59
|
d: ta.Any = yield from self.read(sz)
|
52
60
|
if len(d) != sz:
|
53
61
|
raise EOFError(f'GeneratorReader got {len(d)}, expected {sz}')
|
@@ -67,7 +75,7 @@ class PrependableGeneratorReader(GeneratorReader[AnyT]):
|
|
67
75
|
def _join(self, lst: list[AnyT]) -> AnyT:
|
68
76
|
raise NotImplementedError
|
69
77
|
|
70
|
-
def read(self, sz: int | None) ->
|
78
|
+
def read(self, sz: int | None) -> ReaderGenerator[AnyT, AnyT]:
|
71
79
|
if not self._queue:
|
72
80
|
d: AnyT = check.not_none((yield sz))
|
73
81
|
return d
|
@@ -126,8 +134,6 @@ prependable_str_generator_reader = PrependableStrGeneratorReader
|
|
126
134
|
|
127
135
|
|
128
136
|
class BufferedGeneratorReader(PrependableGeneratorReader[AnyT], abc.ABC):
|
129
|
-
DEFAULT_BUFFER_SIZE = 4 * 0x1000
|
130
|
-
|
131
137
|
def __init__(
|
132
138
|
self,
|
133
139
|
buffer_size: int = DEFAULT_BUFFER_SIZE,
|
@@ -138,7 +144,7 @@ class BufferedGeneratorReader(PrependableGeneratorReader[AnyT], abc.ABC):
|
|
138
144
|
|
139
145
|
self._buffer_size = buffer_size
|
140
146
|
|
141
|
-
def read(self, sz: int | None) ->
|
147
|
+
def read(self, sz: int | None) -> ReaderGenerator[AnyT, AnyT]:
|
142
148
|
g = super().read(sz)
|
143
149
|
i: ta.Any = None
|
144
150
|
while True:
|
omlish/io/generators/stepped.py
CHANGED
@@ -1,18 +1,40 @@
|
|
1
1
|
import typing as ta
|
2
2
|
|
3
|
+
from ... import check
|
3
4
|
from ... import lang
|
5
|
+
from .consts import DEFAULT_BUFFER_SIZE
|
6
|
+
from .direct import BytesDirectGenerator
|
7
|
+
from .direct import StrDirectGenerator
|
4
8
|
|
5
9
|
|
6
10
|
T = ta.TypeVar('T')
|
7
|
-
|
11
|
+
|
8
12
|
O = ta.TypeVar('O')
|
13
|
+
I = ta.TypeVar('I')
|
14
|
+
R = ta.TypeVar('R')
|
15
|
+
|
9
16
|
OF = ta.TypeVar('OF')
|
10
17
|
OT = ta.TypeVar('OT')
|
11
|
-
R = ta.TypeVar('R')
|
12
18
|
|
13
19
|
|
20
|
+
# Stepped generators accept a non-None input, then in response yield zero or more non-None outputs, until yielding None
|
21
|
+
# to signal they need more input again.
|
14
22
|
SteppedGenerator: ta.TypeAlias = ta.Generator[O | None, I | None, R]
|
15
23
|
|
24
|
+
# Conventionally, these are sent and themselves yield an empty value to signify termination.
|
25
|
+
BytesSteppedGenerator: ta.TypeAlias = SteppedGenerator[bytes, bytes, R]
|
26
|
+
StrSteppedGenerator: ta.TypeAlias = SteppedGenerator[str, str, R]
|
27
|
+
|
28
|
+
BytesToStrSteppedGenerator: ta.TypeAlias = SteppedGenerator[str, bytes, R]
|
29
|
+
StrToBytesSteppedGenerator: ta.TypeAlias = SteppedGenerator[bytes, str, R]
|
30
|
+
|
31
|
+
|
32
|
+
# Stepped reader generators emit either an int or None to request input, or emit some other kind of output.
|
33
|
+
SteppedReaderGenerator: ta.TypeAlias = ta.Generator[int | None | O, I | None, R]
|
34
|
+
|
35
|
+
BytesSteppedReaderGenerator: ta.TypeAlias = SteppedReaderGenerator[bytes, bytes, R]
|
36
|
+
StrSteppedReaderGenerator: ta.TypeAlias = SteppedReaderGenerator[str, str, R]
|
37
|
+
|
16
38
|
|
17
39
|
##
|
18
40
|
|
@@ -25,10 +47,8 @@ def flatmap_stepped_generator(
|
|
25
47
|
terminate: ta.Callable[[OF], bool] | None = None,
|
26
48
|
) -> ta.Generator[OT, I, lang.Maybe[R]]:
|
27
49
|
"""
|
28
|
-
Given a
|
29
|
-
|
30
|
-
1:1 generator which accepts input, builds a list of yielded generator output, calls the given function with that
|
31
|
-
list, and yields the result.
|
50
|
+
Given a stepped generator and a function taking a list, returns a direct (1:1) generator which accepts input, builds
|
51
|
+
a list of yielded generator output, calls the given function with that list, and yields the result.
|
32
52
|
|
33
53
|
An optional terminate function may be provided which will cause this function to return early if it returns true for
|
34
54
|
an encountered yielded value. The encountered value causing termination will be included in the list sent to the
|
@@ -89,16 +109,67 @@ def _is_empty(o: T) -> bool:
|
|
89
109
|
return len(o) < 1 # type: ignore
|
90
110
|
|
91
111
|
|
112
|
+
def joined_bytes_stepped_generator(g: BytesSteppedGenerator[R]) -> BytesDirectGenerator[R]:
|
113
|
+
return flatmap_stepped_generator(_join_bytes, g, terminate=_is_empty)
|
114
|
+
|
115
|
+
|
116
|
+
def joined_str_stepped_generator(g: StrSteppedGenerator[R]) -> StrDirectGenerator[R]:
|
117
|
+
return flatmap_stepped_generator(_join_str, g, terminate=_is_empty)
|
118
|
+
|
119
|
+
|
92
120
|
##
|
93
121
|
|
94
122
|
|
95
|
-
def
|
96
|
-
g:
|
97
|
-
|
98
|
-
|
123
|
+
def read_into_bytes_stepped_generator(
|
124
|
+
g: BytesSteppedGenerator,
|
125
|
+
f: ta.IO,
|
126
|
+
*,
|
127
|
+
read_size: int = DEFAULT_BUFFER_SIZE,
|
128
|
+
) -> ta.Iterator[bytes]:
|
129
|
+
yield from lang.genmap( # type: ignore[misc]
|
130
|
+
joined_bytes_stepped_generator(g),
|
131
|
+
lang.readiter(f, read_size),
|
132
|
+
)
|
99
133
|
|
100
134
|
|
101
|
-
def
|
102
|
-
g:
|
103
|
-
|
104
|
-
|
135
|
+
def read_into_str_stepped_generator(
|
136
|
+
g: StrSteppedGenerator,
|
137
|
+
f: ta.TextIO,
|
138
|
+
*,
|
139
|
+
read_size: int = DEFAULT_BUFFER_SIZE,
|
140
|
+
) -> ta.Iterator[str]:
|
141
|
+
yield from lang.genmap(
|
142
|
+
joined_str_stepped_generator(g),
|
143
|
+
lang.readiter(f, read_size),
|
144
|
+
)
|
145
|
+
|
146
|
+
|
147
|
+
##
|
148
|
+
|
149
|
+
|
150
|
+
@lang.autostart
|
151
|
+
def buffer_bytes_stepped_reader_generator(g: BytesSteppedReaderGenerator) -> BytesSteppedGenerator:
|
152
|
+
o = g.send(None)
|
153
|
+
buf: ta.Any = None
|
154
|
+
|
155
|
+
while True:
|
156
|
+
if not buf:
|
157
|
+
buf = check.isinstance((yield None), bytes)
|
158
|
+
|
159
|
+
if o is None or not buf:
|
160
|
+
i = buf
|
161
|
+
elif isinstance(o, int):
|
162
|
+
if len(buf) < o:
|
163
|
+
raise NotImplementedError
|
164
|
+
i = buf[:o]
|
165
|
+
buf = buf[o:]
|
166
|
+
else:
|
167
|
+
raise TypeError(o)
|
168
|
+
|
169
|
+
while True:
|
170
|
+
o = g.send(i)
|
171
|
+
i = None
|
172
|
+
if isinstance(o, bytes):
|
173
|
+
check.none((yield o))
|
174
|
+
else:
|
175
|
+
break
|
omlish/io/pyio.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
"""
|
5
5
|
Python implementation of the io module.
|
6
6
|
|
7
|
-
https://github.com/python/cpython/blob/
|
7
|
+
https://github.com/python/cpython/blob/8b3cccf3f9508572d85b0044519f2bd5715dacad/Lib/_pyio.py
|
8
8
|
"""
|
9
9
|
# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
10
10
|
# --------------------------------------------
|
@@ -2580,8 +2580,11 @@ class TextIOWrapper(TextIOBase):
|
|
2580
2580
|
decoder = self._decoder or self._get_decoder()
|
2581
2581
|
|
2582
2582
|
if size < 0:
|
2583
|
+
chunk = self.buffer.read()
|
2584
|
+
if chunk is None:
|
2585
|
+
raise BlockingIOError("Read returned None.")
|
2583
2586
|
# Read everything.
|
2584
|
-
result = self._get_decoded_chars() + decoder.decode(
|
2587
|
+
result = self._get_decoded_chars() + decoder.decode(chunk, final=True)
|
2585
2588
|
if self._snapshot is not None:
|
2586
2589
|
self._set_decoded_chars('')
|
2587
2590
|
self._snapshot = None
|
omlish/lang/__init__.py
CHANGED
omlish/lang/iterables.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import dataclasses as dc
|
2
|
+
import functools
|
2
3
|
import itertools
|
3
4
|
import typing as ta
|
4
5
|
|
@@ -46,6 +47,25 @@ def interleave(vs: ta.Iterable[T], d: T) -> ta.Iterable[T]:
|
|
46
47
|
yield v
|
47
48
|
|
48
49
|
|
50
|
+
@ta.overload
|
51
|
+
def readiter(f: ta.TextIO, sz: int) -> ta.Iterator[str]:
|
52
|
+
...
|
53
|
+
|
54
|
+
|
55
|
+
@ta.overload
|
56
|
+
def readiter(f: ta.BinaryIO, sz: int) -> ta.Iterator[bytes]:
|
57
|
+
...
|
58
|
+
|
59
|
+
|
60
|
+
@ta.overload
|
61
|
+
def readiter(f: ta.IO, sz: int) -> ta.Iterator[ta.AnyStr]:
|
62
|
+
...
|
63
|
+
|
64
|
+
|
65
|
+
def readiter(f, sz):
|
66
|
+
return iter(functools.partial(f.read, sz), None)
|
67
|
+
|
68
|
+
|
49
69
|
@dc.dataclass(frozen=True)
|
50
70
|
class IterGen(ta.Generic[T]):
|
51
71
|
fn: ta.Callable[[], ta.Iterable[T]]
|