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
omlish/__about__.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
__version__ = '0.0.0.
|
2
|
-
__revision__ = '
|
1
|
+
__version__ = '0.0.0.dev143'
|
2
|
+
__revision__ = '72813c4e4d25f26261452612724f0bce16c77125'
|
3
3
|
|
4
4
|
|
5
5
|
#
|
@@ -48,6 +48,8 @@ class Project(ProjectBase):
|
|
48
48
|
'python-snappy ~= 0.7',
|
49
49
|
|
50
50
|
'zstandard ~= 0.23',
|
51
|
+
|
52
|
+
'brotli ~= 1.1',
|
51
53
|
],
|
52
54
|
|
53
55
|
'diag': [
|
omlish/check.py
CHANGED
omlish/collections/coerce.py
CHANGED
omlish/docker/__init__.py
CHANGED
@@ -14,7 +14,6 @@ from .compose import ( # noqa
|
|
14
14
|
)
|
15
15
|
|
16
16
|
from .helpers import ( # noqa
|
17
|
-
DOCKER_FOR_MAC_HOSTNAME,
|
18
17
|
DOCKER_HOST_PLATFORM_KEY,
|
19
18
|
get_docker_host_platform,
|
20
19
|
timebomb_payload,
|
@@ -32,5 +31,7 @@ from .hub import ( # noqa
|
|
32
31
|
|
33
32
|
|
34
33
|
from ..lite.docker import ( # noqa
|
34
|
+
DOCKER_FOR_MAC_HOSTNAME,
|
35
|
+
|
35
36
|
is_likely_in_docker,
|
36
37
|
)
|
omlish/docker/helpers.py
CHANGED
@@ -21,12 +21,6 @@ def timebomb_payload(delay_s: float, name: str = _DEFAULT_TIMEBOMB_NAME) -> str:
|
|
21
21
|
##
|
22
22
|
|
23
23
|
|
24
|
-
DOCKER_FOR_MAC_HOSTNAME = 'docker.for.mac.localhost'
|
25
|
-
|
26
|
-
|
27
|
-
##
|
28
|
-
|
29
|
-
|
30
24
|
# Set by pyproject, docker-dev script
|
31
25
|
DOCKER_HOST_PLATFORM_KEY = 'DOCKER_HOST_PLATFORM'
|
32
26
|
|
omlish/funcs/pairs.py
CHANGED
@@ -10,9 +10,9 @@ TODO:
|
|
10
10
|
|
11
11
|
Compression choice:
|
12
12
|
- lzma if-available minimal-space
|
13
|
-
- lz4 if-available
|
13
|
+
- lz4 if-available read-heavy
|
14
14
|
- zstd if-available
|
15
|
-
- bz2
|
15
|
+
- bz2 read-heavy (but no parallel decompress)
|
16
16
|
- gz
|
17
17
|
"""
|
18
18
|
import abc
|
omlish/io/compress/__init__.py
CHANGED
omlish/io/compress/abc.py
CHANGED
@@ -9,7 +9,7 @@ import abc
|
|
9
9
|
##
|
10
10
|
|
11
11
|
|
12
|
-
class
|
12
|
+
class CompressorObject(abc.ABC):
|
13
13
|
@abc.abstractmethod
|
14
14
|
def compress(self, data: bytes) -> bytes:
|
15
15
|
"""
|
@@ -36,7 +36,7 @@ class Compressor(abc.ABC):
|
|
36
36
|
##
|
37
37
|
|
38
38
|
|
39
|
-
class
|
39
|
+
class DecompressorObject(abc.ABC):
|
40
40
|
@property
|
41
41
|
@abc.abstractmethod
|
42
42
|
def unused_data(self) -> bytes:
|
@@ -68,7 +68,7 @@ class Decompressor(abc.ABC):
|
|
68
68
|
raise NotImplementedError
|
69
69
|
|
70
70
|
|
71
|
-
class
|
71
|
+
class NeedsInputDecompressorObject(DecompressorObject):
|
72
72
|
"""
|
73
73
|
Used by:
|
74
74
|
- bz2.BZ2Decompressor
|
@@ -85,7 +85,7 @@ class NeedsInputDecompressor(Decompressor):
|
|
85
85
|
raise NotImplementedError
|
86
86
|
|
87
87
|
|
88
|
-
class
|
88
|
+
class UnconsumedTailDecompressorObject(DecompressorObject):
|
89
89
|
"""
|
90
90
|
Used by:
|
91
91
|
- zlib.decompressobj
|
omlish/io/compress/adapters.py
CHANGED
@@ -37,26 +37,26 @@
|
|
37
37
|
import typing as ta
|
38
38
|
|
39
39
|
from ... import check
|
40
|
-
from
|
41
|
-
from
|
42
|
-
from .abc import
|
43
|
-
from .
|
44
|
-
from .
|
40
|
+
from ..generators import BytesSteppedGenerator
|
41
|
+
from ..generators import BytesSteppedReaderGenerator
|
42
|
+
from .abc import CompressorObject
|
43
|
+
from .abc import NeedsInputDecompressorObject
|
44
|
+
from .abc import UnconsumedTailDecompressorObject
|
45
45
|
|
46
46
|
|
47
47
|
##
|
48
48
|
|
49
49
|
|
50
|
-
class
|
50
|
+
class CompressorObjectIncrementalAdapter:
|
51
51
|
def __init__(
|
52
52
|
self,
|
53
|
-
factory: ta.Callable[...,
|
53
|
+
factory: ta.Callable[..., CompressorObject],
|
54
54
|
) -> None:
|
55
55
|
super().__init__()
|
56
56
|
|
57
57
|
self._factory = factory
|
58
58
|
|
59
|
-
def __call__(self) ->
|
59
|
+
def __call__(self) -> BytesSteppedGenerator:
|
60
60
|
compressor = self._factory()
|
61
61
|
|
62
62
|
while True:
|
@@ -77,10 +77,10 @@ class CompressorIncrementalAdapter:
|
|
77
77
|
##
|
78
78
|
|
79
79
|
|
80
|
-
class
|
80
|
+
class DecompressorObjectIncrementalAdapter:
|
81
81
|
def __init__(
|
82
82
|
self,
|
83
|
-
factory: ta.Callable[...,
|
83
|
+
factory: ta.Callable[..., NeedsInputDecompressorObject | UnconsumedTailDecompressorObject],
|
84
84
|
*,
|
85
85
|
trailing_error: type[BaseException] | tuple[type[BaseException], ...] = (),
|
86
86
|
) -> None:
|
@@ -89,7 +89,7 @@ class DecompressorIncrementalAdapter:
|
|
89
89
|
self._factory = factory
|
90
90
|
self._trailing_error = trailing_error
|
91
91
|
|
92
|
-
def __call__(self) ->
|
92
|
+
def __call__(self) -> BytesSteppedReaderGenerator:
|
93
93
|
pos = 0
|
94
94
|
|
95
95
|
data = None # Default if EOF is encountered
|
@@ -145,3 +145,4 @@ class DecompressorIncrementalAdapter:
|
|
145
145
|
|
146
146
|
pos += len(data)
|
147
147
|
check.none((yield data))
|
148
|
+
data = None
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import abc
|
2
|
+
|
3
|
+
from ..generators import BytesSteppedGenerator
|
4
|
+
from ..generators import BytesSteppedReaderGenerator
|
5
|
+
|
6
|
+
|
7
|
+
class Compression(abc.ABC):
|
8
|
+
@abc.abstractmethod
|
9
|
+
def compress(self, d: bytes) -> bytes:
|
10
|
+
raise NotImplementedError
|
11
|
+
|
12
|
+
@abc.abstractmethod
|
13
|
+
def decompress(self, d: bytes) -> bytes:
|
14
|
+
raise NotImplementedError
|
15
|
+
|
16
|
+
|
17
|
+
class IncrementalCompression(abc.ABC):
|
18
|
+
@abc.abstractmethod
|
19
|
+
def compress_incremental(self) -> BytesSteppedGenerator[None]:
|
20
|
+
raise NotImplementedError
|
21
|
+
|
22
|
+
@abc.abstractmethod
|
23
|
+
def decompress_incremental(self) -> BytesSteppedReaderGenerator[None]:
|
24
|
+
raise NotImplementedError
|
@@ -0,0 +1,33 @@
|
|
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 brotli
|
10
|
+
else:
|
11
|
+
brotli = lang.proxy_import('brotli')
|
12
|
+
|
13
|
+
|
14
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
15
|
+
class SnappyCompression(Compression):
|
16
|
+
mode: int | None = None
|
17
|
+
quality: int | None = None
|
18
|
+
lgwin: int | None = None
|
19
|
+
lgblock: int | None = None
|
20
|
+
|
21
|
+
def compress(self, d: bytes) -> bytes:
|
22
|
+
return brotli.compress(
|
23
|
+
d,
|
24
|
+
**(dict(mode=self.mode) if self.mode is not None else {}),
|
25
|
+
**(dict(mode=self.quality) if self.quality is not None else {}),
|
26
|
+
**(dict(mode=self.lgwin) if self.lgwin is not None else {}),
|
27
|
+
**(dict(mode=self.lgblock) if self.lgblock is not None else {}),
|
28
|
+
)
|
29
|
+
|
30
|
+
def decompress(self, d: bytes) -> bytes:
|
31
|
+
return brotli.decompress(
|
32
|
+
d,
|
33
|
+
)
|
omlish/io/compress/bz2.py
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
+
import dataclasses as dc
|
1
2
|
import functools
|
2
3
|
import typing as ta
|
3
4
|
|
4
5
|
from ... import lang
|
5
|
-
from
|
6
|
-
from
|
7
|
-
from .
|
8
|
-
from .
|
6
|
+
from ..generators import BytesSteppedGenerator
|
7
|
+
from ..generators import BytesSteppedReaderGenerator
|
8
|
+
from .adapters import CompressorObjectIncrementalAdapter
|
9
|
+
from .adapters import DecompressorObjectIncrementalAdapter
|
10
|
+
from .base import Compression
|
11
|
+
from .base import IncrementalCompression
|
9
12
|
|
10
13
|
|
11
14
|
if ta.TYPE_CHECKING:
|
@@ -14,29 +17,31 @@ else:
|
|
14
17
|
bz2 = lang.proxy_import('bz2')
|
15
18
|
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
*,
|
21
|
-
compresslevel: int = 9,
|
22
|
-
) -> None:
|
23
|
-
super().__init__()
|
20
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
21
|
+
class Bz2Compression(Compression, IncrementalCompression):
|
22
|
+
level: int = 9
|
24
23
|
|
25
|
-
|
24
|
+
def compress(self, d: bytes) -> bytes:
|
25
|
+
return bz2.compress(
|
26
|
+
d,
|
27
|
+
self.level,
|
28
|
+
)
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
def decompress(self, d: bytes) -> bytes:
|
31
|
+
return bz2.decompress(
|
32
|
+
d,
|
33
|
+
)
|
34
|
+
|
35
|
+
def compress_incremental(self) -> BytesSteppedGenerator[None]:
|
36
|
+
return lang.nextgen(CompressorObjectIncrementalAdapter(
|
30
37
|
functools.partial(
|
31
38
|
bz2.BZ2Compressor, # type: ignore
|
32
|
-
self.
|
39
|
+
self.level,
|
33
40
|
),
|
34
|
-
)()
|
35
|
-
|
41
|
+
)())
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
return DecompressorIncrementalAdapter(
|
43
|
+
def decompress_incremental(self) -> BytesSteppedReaderGenerator[None]:
|
44
|
+
return DecompressorObjectIncrementalAdapter(
|
40
45
|
bz2.BZ2Decompressor, # type: ignore
|
41
46
|
trailing_error=OSError,
|
42
47
|
)()
|
omlish/io/compress/gzip.py
CHANGED
@@ -33,6 +33,7 @@
|
|
33
33
|
#
|
34
34
|
# 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this
|
35
35
|
# License Agreement.
|
36
|
+
import dataclasses as dc
|
36
37
|
import functools
|
37
38
|
import os.path
|
38
39
|
import struct
|
@@ -42,9 +43,11 @@ import typing as ta
|
|
42
43
|
from ... import cached
|
43
44
|
from ... import check
|
44
45
|
from ... import lang
|
46
|
+
from ..generators import BytesSteppedGenerator
|
47
|
+
from ..generators import BytesSteppedReaderGenerator
|
45
48
|
from ..generators.readers import PrependableBytesGeneratorReader
|
46
|
-
from .
|
47
|
-
from .
|
49
|
+
from .base import Compression
|
50
|
+
from .base import IncrementalCompression
|
48
51
|
|
49
52
|
|
50
53
|
if ta.TYPE_CHECKING:
|
@@ -63,6 +66,37 @@ COMPRESS_LEVEL_TRADEOFF = 6
|
|
63
66
|
COMPRESS_LEVEL_BEST = 9
|
64
67
|
|
65
68
|
|
69
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
70
|
+
class GzipCompression(Compression, IncrementalCompression):
|
71
|
+
level: int = COMPRESS_LEVEL_BEST
|
72
|
+
|
73
|
+
mtime: float | None = None
|
74
|
+
|
75
|
+
def compress(self, d: bytes) -> bytes:
|
76
|
+
return gzip.compress(
|
77
|
+
d,
|
78
|
+
self.level,
|
79
|
+
mtime=self.mtime,
|
80
|
+
)
|
81
|
+
|
82
|
+
def decompress(self, d: bytes) -> bytes:
|
83
|
+
return gzip.decompress(
|
84
|
+
d,
|
85
|
+
)
|
86
|
+
|
87
|
+
def compress_incremental(self) -> BytesSteppedGenerator[None]:
|
88
|
+
return lang.nextgen(IncrementalGzipCompressor(
|
89
|
+
level=self.level,
|
90
|
+
mtime=self.mtime,
|
91
|
+
)())
|
92
|
+
|
93
|
+
def decompress_incremental(self) -> BytesSteppedReaderGenerator[None]:
|
94
|
+
return IncrementalGzipDecompressor()()
|
95
|
+
|
96
|
+
|
97
|
+
##
|
98
|
+
|
99
|
+
|
66
100
|
@cached.function
|
67
101
|
def _zero_crc() -> int:
|
68
102
|
return zlib.crc32(b'')
|
@@ -75,14 +109,14 @@ class IncrementalGzipCompressor:
|
|
75
109
|
def __init__(
|
76
110
|
self,
|
77
111
|
*,
|
78
|
-
|
112
|
+
level: int = COMPRESS_LEVEL_BEST,
|
79
113
|
name: str | bytes | None = None,
|
80
114
|
mtime: float | None = None,
|
81
115
|
) -> None:
|
82
116
|
super().__init__()
|
83
117
|
|
84
118
|
self._name = name or ''
|
85
|
-
self.
|
119
|
+
self._level = level
|
86
120
|
self._mtime = mtime
|
87
121
|
|
88
122
|
def _write_gzip_header(self) -> ta.Generator[bytes, None, None]:
|
@@ -110,9 +144,9 @@ class IncrementalGzipCompressor:
|
|
110
144
|
mtime = time.time()
|
111
145
|
check.none((yield struct.pack('<L', int(mtime))))
|
112
146
|
|
113
|
-
if self.
|
147
|
+
if self._level == COMPRESS_LEVEL_BEST:
|
114
148
|
xfl = b'\002'
|
115
|
-
elif self.
|
149
|
+
elif self._level == COMPRESS_LEVEL_FAST:
|
116
150
|
xfl = b'\004'
|
117
151
|
else:
|
118
152
|
xfl = b'\000'
|
@@ -123,15 +157,14 @@ class IncrementalGzipCompressor:
|
|
123
157
|
if fname:
|
124
158
|
check.none((yield fname + b'\000'))
|
125
159
|
|
126
|
-
|
127
|
-
def __call__(self) -> IncrementalCompressor:
|
160
|
+
def __call__(self) -> BytesSteppedGenerator:
|
128
161
|
crc = _zero_crc()
|
129
162
|
size = 0
|
130
163
|
offset = 0 # Current file offset for seek(), tell(), etc
|
131
164
|
wrote_header = False
|
132
165
|
|
133
166
|
compress = zlib.compressobj(
|
134
|
-
self.
|
167
|
+
self._level,
|
135
168
|
zlib.DEFLATED,
|
136
169
|
-zlib.MAX_WBITS,
|
137
170
|
zlib.DEF_MEM_LEVEL,
|
@@ -251,7 +284,7 @@ class IncrementalGzipDecompressor:
|
|
251
284
|
if c:
|
252
285
|
rdr.prepend(c)
|
253
286
|
|
254
|
-
def __call__(self) ->
|
287
|
+
def __call__(self) -> BytesSteppedReaderGenerator:
|
255
288
|
rdr = PrependableBytesGeneratorReader()
|
256
289
|
|
257
290
|
pos = 0 # Current offset in decompressed stream
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import dataclasses as dc
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from ... import check
|
5
|
+
from ... import lang
|
6
|
+
from ..generators import BytesSteppedGenerator
|
7
|
+
from .base import Compression
|
8
|
+
from .base import IncrementalCompression
|
9
|
+
|
10
|
+
|
11
|
+
if ta.TYPE_CHECKING:
|
12
|
+
import lz4.frame as lz4_frame
|
13
|
+
else:
|
14
|
+
lz4_frame = lang.proxy_import('lz4.frame')
|
15
|
+
|
16
|
+
|
17
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
18
|
+
class Lz4Compression(Compression, IncrementalCompression):
|
19
|
+
level: int = 0
|
20
|
+
|
21
|
+
block_size: int = 0
|
22
|
+
block_linked: bool = True
|
23
|
+
block_checksum: bool = False
|
24
|
+
content_checksum: bool = False
|
25
|
+
store_size: bool = True
|
26
|
+
auto_flush: bool = False
|
27
|
+
|
28
|
+
def compress(self, d: bytes) -> bytes:
|
29
|
+
return lz4_frame.compress(
|
30
|
+
d,
|
31
|
+
compression_level=self.level,
|
32
|
+
block_size=self.block_size,
|
33
|
+
content_checksum=self.content_checksum,
|
34
|
+
block_linked=self.block_linked,
|
35
|
+
store_size=self.store_size,
|
36
|
+
)
|
37
|
+
|
38
|
+
def decompress(self, d: bytes) -> bytes:
|
39
|
+
return lz4_frame.decompress(
|
40
|
+
d,
|
41
|
+
)
|
42
|
+
|
43
|
+
@lang.autostart
|
44
|
+
def compress_incremental(self) -> BytesSteppedGenerator[None]:
|
45
|
+
with lz4_frame.LZ4FrameCompressor(
|
46
|
+
compression_level=self.level,
|
47
|
+
block_size=self.block_size,
|
48
|
+
block_linked=self.block_linked,
|
49
|
+
block_checksum=self.block_checksum,
|
50
|
+
content_checksum=self.content_checksum,
|
51
|
+
auto_flush=self.auto_flush,
|
52
|
+
) as compressor:
|
53
|
+
started = False
|
54
|
+
while True:
|
55
|
+
i = check.isinstance((yield None), bytes)
|
56
|
+
if not started:
|
57
|
+
yield compressor.begin()
|
58
|
+
started = True
|
59
|
+
if not i:
|
60
|
+
yield compressor.flush()
|
61
|
+
yield b''
|
62
|
+
return
|
63
|
+
if (o := compressor.compress(i)):
|
64
|
+
yield o
|
65
|
+
|
66
|
+
@lang.autostart
|
67
|
+
def decompress_incremental(self) -> BytesSteppedGenerator[None]:
|
68
|
+
# lz4 lib does internal buffering so this is simply a BytesSteppedGenerator not a BytesSteppedReaderGenerator as
|
69
|
+
# it only yields None, accepting any number of bytes at a time.
|
70
|
+
with lz4_frame.LZ4FrameDecompressor() as decompressor:
|
71
|
+
while True:
|
72
|
+
i = check.isinstance((yield None), bytes)
|
73
|
+
if not i:
|
74
|
+
yield b''
|
75
|
+
return
|
76
|
+
if (o := decompressor.decompress(i)):
|
77
|
+
yield o
|
omlish/io/compress/lzma.py
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
+
import dataclasses as dc
|
2
|
+
import functools
|
1
3
|
import typing as ta
|
2
4
|
|
3
5
|
from ... import lang
|
4
|
-
from
|
5
|
-
from
|
6
|
-
from .
|
7
|
-
from .
|
6
|
+
from ..generators import BytesSteppedGenerator
|
7
|
+
from ..generators import BytesSteppedReaderGenerator
|
8
|
+
from .adapters import CompressorObjectIncrementalAdapter
|
9
|
+
from .adapters import DecompressorObjectIncrementalAdapter
|
10
|
+
from .base import Compression
|
11
|
+
from .base import IncrementalCompression
|
8
12
|
|
9
13
|
|
10
14
|
if ta.TYPE_CHECKING:
|
@@ -13,20 +17,51 @@ else:
|
|
13
17
|
lzma = lang.proxy_import('lzma')
|
14
18
|
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
21
|
+
class LzmaCompression(Compression, IncrementalCompression):
|
22
|
+
format: int | None = None
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
check: int = -1
|
25
|
+
preset: int | None = None
|
26
|
+
filters: dict | None = None
|
27
|
+
|
28
|
+
mem_limit: int | None = None
|
29
|
+
|
30
|
+
def compress(self, d: bytes) -> bytes:
|
31
|
+
return lzma.compress(
|
32
|
+
d,
|
33
|
+
format=self.format if self.format is not None else lzma.FORMAT_XZ,
|
34
|
+
check=self.check,
|
35
|
+
preset=self.preset,
|
36
|
+
filters=self.filters, # type: ignore[arg-type]
|
37
|
+
)
|
38
|
+
|
39
|
+
def decompress(self, d: bytes) -> bytes:
|
40
|
+
return lzma.decompress(
|
41
|
+
d,
|
42
|
+
format=self.format if self.format is not None else lzma.FORMAT_AUTO,
|
43
|
+
memlimit=self.mem_limit,
|
44
|
+
filters=self.filters, # type: ignore[arg-type]
|
45
|
+
)
|
25
46
|
|
47
|
+
def compress_incremental(self) -> BytesSteppedGenerator[None]:
|
48
|
+
return lang.nextgen(CompressorObjectIncrementalAdapter(
|
49
|
+
functools.partial( # type: ignore
|
50
|
+
lzma.LZMACompressor,
|
51
|
+
format=self.format if self.format is not None else lzma.FORMAT_XZ,
|
52
|
+
check=self.check,
|
53
|
+
preset=self.preset,
|
54
|
+
filters=self.filters, # type: ignore[arg-type]
|
55
|
+
),
|
56
|
+
)())
|
26
57
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
58
|
+
def decompress_incremental(self) -> BytesSteppedReaderGenerator[None]:
|
59
|
+
return DecompressorObjectIncrementalAdapter(
|
60
|
+
functools.partial( # type: ignore
|
61
|
+
lzma.LZMADecompressor,
|
62
|
+
format=self.format if self.format is not None else lzma.FORMAT_AUTO,
|
63
|
+
memlimit=self.mem_limit,
|
64
|
+
filters=self.filters, # type: ignore[arg-type]
|
65
|
+
),
|
31
66
|
trailing_error=lzma.LZMAError,
|
32
67
|
)()
|
@@ -0,0 +1,20 @@
|
|
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 snappy
|
10
|
+
else:
|
11
|
+
snappy = lang.proxy_import('snappy')
|
12
|
+
|
13
|
+
|
14
|
+
@dc.dataclass(frozen=True)
|
15
|
+
class SnappyCompression(Compression):
|
16
|
+
def compress(self, d: bytes) -> bytes:
|
17
|
+
return snappy.compress(d)
|
18
|
+
|
19
|
+
def decompress(self, d: bytes) -> bytes:
|
20
|
+
return snappy.decompress(d)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import dataclasses as dc
|
2
|
+
import functools
|
3
|
+
import typing as ta
|
4
|
+
|
5
|
+
from ... import lang
|
6
|
+
from ..generators import BytesSteppedGenerator
|
7
|
+
from ..generators import BytesSteppedReaderGenerator
|
8
|
+
from .adapters import CompressorObjectIncrementalAdapter
|
9
|
+
from .adapters import DecompressorObjectIncrementalAdapter
|
10
|
+
from .base import Compression
|
11
|
+
from .base import IncrementalCompression
|
12
|
+
|
13
|
+
|
14
|
+
if ta.TYPE_CHECKING:
|
15
|
+
import zlib
|
16
|
+
else:
|
17
|
+
zlib = lang.proxy_import('zlib')
|
18
|
+
|
19
|
+
|
20
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
21
|
+
class ZlibCompression(Compression, IncrementalCompression):
|
22
|
+
level: int = 9
|
23
|
+
|
24
|
+
wbits: int | None = None
|
25
|
+
strategy: int | None = None
|
26
|
+
zdict: bytes | None = None
|
27
|
+
|
28
|
+
def compress(self, d: bytes) -> bytes:
|
29
|
+
return zlib.compress(
|
30
|
+
d,
|
31
|
+
self.level,
|
32
|
+
**(dict(wbits=self.wbits) if self.wbits is not None else {}),
|
33
|
+
)
|
34
|
+
|
35
|
+
def decompress(self, d: bytes) -> bytes:
|
36
|
+
return zlib.decompress(
|
37
|
+
d,
|
38
|
+
**(dict(wbits=self.wbits) if self.wbits is not None else {}),
|
39
|
+
)
|
40
|
+
|
41
|
+
def compress_incremental(self) -> BytesSteppedGenerator[None]:
|
42
|
+
return lang.nextgen(CompressorObjectIncrementalAdapter(
|
43
|
+
functools.partial(
|
44
|
+
zlib.compressobj, # type: ignore
|
45
|
+
self.level,
|
46
|
+
**(dict(wbits=self.wbits) if self.wbits is not None else {}), # type: ignore[arg-type]
|
47
|
+
**(dict(strategy=self.strategy) if self.strategy is not None else {}), # type: ignore[arg-type]
|
48
|
+
**(dict(zdict=self.zdict) if self.zdict is not None else {}), # type: ignore[arg-type]
|
49
|
+
),
|
50
|
+
)())
|
51
|
+
|
52
|
+
def decompress_incremental(self) -> BytesSteppedReaderGenerator[None]:
|
53
|
+
return DecompressorObjectIncrementalAdapter(
|
54
|
+
functools.partial( # type: ignore
|
55
|
+
zlib.decompressobj,
|
56
|
+
**(dict(wbits=self.wbits) if self.wbits is not None else {}), # type: ignore[arg-type]
|
57
|
+
**(dict(zdict=self.zdict) if self.zdict is not None else {}), # type: ignore[arg-type]
|
58
|
+
),
|
59
|
+
trailing_error=OSError,
|
60
|
+
)()
|