Skip to content

Commit 798f332

Browse files
authored
Python 3.14: PEP-784 compression.zstd (#14129)
1 parent 0c4ae3e commit 798f332

File tree

8 files changed

+314
-11
lines changed

8 files changed

+314
-11
lines changed

stdlib/@tests/stubtest_allowlists/py314.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ compression.gzip.GzipFile.readinto
99
compression.gzip.GzipFile.readinto1
1010
compression.gzip.GzipFile.readinto1
1111
compression.gzip.compress
12-
compression.zstd
1312
fractions.Fraction.__pow__
1413
fractions.Fraction.__rpow__
1514
gzip.GzipFile.readinto

stdlib/VERSIONS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ _warnings: 3.0-
7676
_weakref: 3.0-
7777
_weakrefset: 3.0-
7878
_winapi: 3.3-
79+
_zstd: 3.14-
7980
abc: 3.0-
8081
aifc: 3.0-3.12
8182
annotationlib: 3.14-

stdlib/_zstd.pyi

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
from _typeshed import ReadableBuffer
2+
from collections.abc import Mapping
3+
from compression.zstd import CompressionParameter, DecompressionParameter
4+
from typing import Final, Literal, final
5+
from typing_extensions import Self, TypeAlias
6+
7+
ZSTD_CLEVEL_DEFAULT: Final = 3
8+
ZSTD_DStreamOutSize: Final = 131072
9+
ZSTD_btlazy2: Final = 6
10+
ZSTD_btopt: Final = 7
11+
ZSTD_btultra: Final = 8
12+
ZSTD_btultra2: Final = 9
13+
ZSTD_c_chainLog: Final = 103
14+
ZSTD_c_checksumFlag: Final = 201
15+
ZSTD_c_compressionLevel: Final = 100
16+
ZSTD_c_contentSizeFlag: Final = 200
17+
ZSTD_c_dictIDFlag: Final = 202
18+
ZSTD_c_enableLongDistanceMatching: Final = 160
19+
ZSTD_c_hashLog: Final = 102
20+
ZSTD_c_jobSize: Final = 401
21+
ZSTD_c_ldmBucketSizeLog: Final = 163
22+
ZSTD_c_ldmHashLog: Final = 161
23+
ZSTD_c_ldmHashRateLog: Final = 164
24+
ZSTD_c_ldmMinMatch: Final = 162
25+
ZSTD_c_minMatch: Final = 105
26+
ZSTD_c_nbWorkers: Final = 400
27+
ZSTD_c_overlapLog: Final = 402
28+
ZSTD_c_searchLog: Final = 104
29+
ZSTD_c_strategy: Final = 107
30+
ZSTD_c_targetLength: Final = 106
31+
ZSTD_c_windowLog: Final = 101
32+
ZSTD_d_windowLogMax: Final = 100
33+
ZSTD_dfast: Final = 2
34+
ZSTD_fast: Final = 1
35+
ZSTD_greedy: Final = 3
36+
ZSTD_lazy: Final = 4
37+
ZSTD_lazy2: Final = 5
38+
39+
_ZstdCompressorContinue: TypeAlias = Literal[0]
40+
_ZstdCompressorFlushBlock: TypeAlias = Literal[1]
41+
_ZstdCompressorFlushFrame: TypeAlias = Literal[2]
42+
43+
@final
44+
class ZstdCompressor:
45+
CONTINUE: Final = 0
46+
FLUSH_BLOCK: Final = 1
47+
FLUSH_FRAME: Final = 2
48+
def __init__(
49+
self, level: int | None = None, options: Mapping[int, int] | None = None, zstd_dict: ZstdDict | None = None
50+
) -> None: ...
51+
def compress(
52+
self, /, data: ReadableBuffer, mode: _ZstdCompressorContinue | _ZstdCompressorFlushBlock | _ZstdCompressorFlushFrame = 0
53+
) -> bytes: ...
54+
def flush(self, /, mode: _ZstdCompressorFlushBlock | _ZstdCompressorFlushFrame = 2) -> bytes: ...
55+
@property
56+
def last_mode(self) -> _ZstdCompressorContinue | _ZstdCompressorFlushBlock | _ZstdCompressorFlushFrame: ...
57+
58+
@final
59+
class ZstdDecompressor:
60+
def __init__(self, zstd_dict: ZstdDict | None = None, options: Mapping[int, int] | None = None) -> None: ...
61+
def decompress(self, /, data: ReadableBuffer, max_length: int = -1) -> bytes: ...
62+
@property
63+
def eof(self) -> bool: ...
64+
@property
65+
def needs_input(self) -> bool: ...
66+
@property
67+
def unused_data(self) -> bytes: ...
68+
69+
@final
70+
class ZstdDict:
71+
def __init__(self, dict_content: bytes, /, *, is_raw: bool = False) -> None: ...
72+
def __len__(self, /) -> int: ...
73+
@property
74+
def as_digested_dict(self) -> tuple[Self, int]: ...
75+
@property
76+
def as_prefix(self) -> tuple[Self, int]: ...
77+
@property
78+
def as_undigested_dict(self) -> tuple[Self, int]: ...
79+
@property
80+
def dict_content(self) -> bytes: ...
81+
@property
82+
def dict_id(self) -> int: ...
83+
84+
class ZstdError(Exception): ...
85+
86+
def finalize_dict(
87+
custom_dict_bytes: bytes, samples_bytes: bytes, samples_sizes: tuple[int, ...], dict_size: int, compression_level: int, /
88+
) -> bytes: ...
89+
def get_frame_info(frame_buffer: ReadableBuffer) -> tuple[int, int]: ...
90+
def get_frame_size(frame_buffer: ReadableBuffer) -> int: ...
91+
def get_param_bounds(parameter: int, is_compress: bool) -> tuple[int, int]: ...
92+
def set_parameter_types(c_parameter_type: type[CompressionParameter], d_parameter_type: type[DecompressionParameter]) -> None: ...
93+
def train_dict(samples_bytes: bytes, samples_sizes: tuple[int, ...], dict_size: int, /) -> bytes: ...
94+
95+
zstd_version: Final[str]
96+
zstd_version_number: Final[int]

stdlib/bz2.pyi

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import sys
22
from _bz2 import BZ2Compressor as BZ2Compressor, BZ2Decompressor as BZ2Decompressor
33
from _typeshed import ReadableBuffer, StrOrBytesPath, WriteableBuffer
44
from collections.abc import Iterable
5-
from typing import IO, Literal, Protocol, SupportsIndex, TextIO, overload
5+
from io import TextIOWrapper
6+
from typing import IO, Literal, Protocol, SupportsIndex, overload
67
from typing_extensions import Self, TypeAlias
78

89
if sys.version_info >= (3, 14):
@@ -48,7 +49,7 @@ def open(
4849
encoding: str | None = None,
4950
errors: str | None = None,
5051
newline: str | None = None,
51-
) -> TextIO: ...
52+
) -> TextIOWrapper: ...
5253
@overload
5354
def open(
5455
filename: _WritableFileobj,
@@ -66,7 +67,7 @@ def open(
6667
encoding: str | None = None,
6768
errors: str | None = None,
6869
newline: str | None = None,
69-
) -> TextIO: ...
70+
) -> TextIOWrapper: ...
7071
@overload
7172
def open(
7273
filename: StrOrBytesPath,
@@ -84,7 +85,7 @@ def open(
8485
encoding: str | None = None,
8586
errors: str | None = None,
8687
newline: str | None = None,
87-
) -> TextIO: ...
88+
) -> TextIOWrapper: ...
8889
@overload
8990
def open(
9091
filename: StrOrBytesPath | _ReadableFileobj | _WritableFileobj,
@@ -93,7 +94,7 @@ def open(
9394
encoding: str | None = None,
9495
errors: str | None = None,
9596
newline: str | None = None,
96-
) -> BZ2File | TextIO: ...
97+
) -> BZ2File | TextIOWrapper: ...
9798

9899
class BZ2File(BaseStream, IO[bytes]):
99100
def __enter__(self) -> Self: ...

stdlib/compression/_common/_streams.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from _typeshed import Incomplete, WriteableBuffer
22
from collections.abc import Callable
33
from io import DEFAULT_BUFFER_SIZE, BufferedIOBase, RawIOBase
4-
from typing import Any, Protocol
4+
from typing import Any, Protocol, type_check_only
55

66
BUFFER_SIZE = DEFAULT_BUFFER_SIZE
77

8+
@type_check_only
89
class _Reader(Protocol):
910
def read(self, n: int, /) -> bytes: ...
1011
def seekable(self) -> bool: ...

stdlib/compression/zstd/__init__.pyi

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import enum
2+
from _typeshed import ReadableBuffer
3+
from collections.abc import Iterable, Mapping
4+
from compression.zstd._zstdfile import ZstdFile, open
5+
from typing import Final, final
6+
7+
import _zstd
8+
from _zstd import ZstdCompressor, ZstdDecompressor, ZstdDict, ZstdError, get_frame_size, zstd_version
9+
10+
__all__ = (
11+
# compression.zstd
12+
"COMPRESSION_LEVEL_DEFAULT",
13+
"compress",
14+
"CompressionParameter",
15+
"decompress",
16+
"DecompressionParameter",
17+
"finalize_dict",
18+
"get_frame_info",
19+
"Strategy",
20+
"train_dict",
21+
# compression.zstd._zstdfile
22+
"open",
23+
"ZstdFile",
24+
# _zstd
25+
"get_frame_size",
26+
"zstd_version",
27+
"zstd_version_info",
28+
"ZstdCompressor",
29+
"ZstdDecompressor",
30+
"ZstdDict",
31+
"ZstdError",
32+
)
33+
34+
zstd_version_info: Final[tuple[int, int, int]]
35+
COMPRESSION_LEVEL_DEFAULT: Final = _zstd.ZSTD_CLEVEL_DEFAULT
36+
37+
class FrameInfo:
38+
decompressed_size: int
39+
dictionary_id: int
40+
def __init__(self, decompressed_size: int, dictionary_id: int) -> None: ...
41+
42+
def get_frame_info(frame_buffer: ReadableBuffer) -> FrameInfo: ...
43+
def train_dict(samples: Iterable[ReadableBuffer], dict_size: int) -> ZstdDict: ...
44+
def finalize_dict(zstd_dict: ZstdDict, /, samples: Iterable[ReadableBuffer], dict_size: int, level: int) -> ZstdDict: ...
45+
def compress(
46+
data: ReadableBuffer, level: int | None = None, options: Mapping[int, int] | None = None, zstd_dict: ZstdDict | None = None
47+
) -> bytes: ...
48+
def decompress(data: ReadableBuffer, zstd_dict: ZstdDict | None = None, options: Mapping[int, int] | None = None) -> bytes: ...
49+
@final
50+
class CompressionParameter(enum.IntEnum):
51+
compression_level = _zstd.ZSTD_c_compressionLevel
52+
window_log = _zstd.ZSTD_c_windowLog
53+
hash_log = _zstd.ZSTD_c_hashLog
54+
chain_log = _zstd.ZSTD_c_chainLog
55+
search_log = _zstd.ZSTD_c_searchLog
56+
min_match = _zstd.ZSTD_c_minMatch
57+
target_length = _zstd.ZSTD_c_targetLength
58+
strategy = _zstd.ZSTD_c_strategy
59+
enable_long_distance_matching = _zstd.ZSTD_c_enableLongDistanceMatching
60+
ldm_hash_log = _zstd.ZSTD_c_ldmHashLog
61+
ldm_min_match = _zstd.ZSTD_c_ldmMinMatch
62+
ldm_bucket_size_log = _zstd.ZSTD_c_ldmBucketSizeLog
63+
ldm_hash_rate_log = _zstd.ZSTD_c_ldmHashRateLog
64+
content_size_flag = _zstd.ZSTD_c_contentSizeFlag
65+
checksum_flag = _zstd.ZSTD_c_checksumFlag
66+
dict_id_flag = _zstd.ZSTD_c_dictIDFlag
67+
nb_workers = _zstd.ZSTD_c_nbWorkers
68+
job_size = _zstd.ZSTD_c_jobSize
69+
overlap_log = _zstd.ZSTD_c_overlapLog
70+
def bounds(self) -> tuple[int, int]: ...
71+
72+
@final
73+
class DecompressionParameter(enum.IntEnum):
74+
window_log_max = _zstd.ZSTD_d_windowLogMax
75+
def bounds(self) -> tuple[int, int]: ...
76+
77+
@final
78+
class Strategy(enum.IntEnum):
79+
fast = _zstd.ZSTD_fast
80+
dfast = _zstd.ZSTD_dfast
81+
greedy = _zstd.ZSTD_greedy
82+
lazy = _zstd.ZSTD_lazy
83+
lazy2 = _zstd.ZSTD_lazy2
84+
btlazy2 = _zstd.ZSTD_btlazy2
85+
btopt = _zstd.ZSTD_btopt
86+
btultra = _zstd.ZSTD_btultra
87+
btultra2 = _zstd.ZSTD_btultra2

stdlib/compression/zstd/_zstdfile.pyi

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
from _typeshed import ReadableBuffer, StrOrBytesPath, SupportsWrite, WriteableBuffer
2+
from collections.abc import Mapping
3+
from compression._common import _streams
4+
from compression.zstd import ZstdDict
5+
from io import TextIOWrapper, _WrappedBuffer
6+
from typing import Literal, overload, type_check_only
7+
from typing_extensions import TypeAlias
8+
9+
from _zstd import ZstdCompressor, _ZstdCompressorFlushBlock, _ZstdCompressorFlushFrame
10+
11+
__all__ = ("ZstdFile", "open")
12+
13+
_ReadBinaryMode: TypeAlias = Literal["r", "rb"]
14+
_WriteBinaryMode: TypeAlias = Literal["w", "wb", "x", "xb", "a", "ab"]
15+
_ReadTextMode: TypeAlias = Literal["rt"]
16+
_WriteTextMode: TypeAlias = Literal["wt", "xt", "at"]
17+
18+
@type_check_only
19+
class _FileBinaryRead(_streams._Reader):
20+
def close(self) -> None: ...
21+
22+
@type_check_only
23+
class _FileBinaryWrite(SupportsWrite[bytes]):
24+
def close(self) -> None: ...
25+
26+
class ZstdFile(_streams.BaseStream):
27+
FLUSH_BLOCK = ZstdCompressor.FLUSH_BLOCK
28+
FLUSH_FRAME = ZstdCompressor.FLUSH_FRAME
29+
30+
@overload
31+
def __init__(
32+
self,
33+
file: StrOrBytesPath | _FileBinaryRead,
34+
/,
35+
mode: _ReadBinaryMode = "r",
36+
*,
37+
level: None = None,
38+
options: Mapping[int, int] | None = None,
39+
zstd_dict: ZstdDict | None = None,
40+
) -> None: ...
41+
@overload
42+
def __init__(
43+
self,
44+
file: StrOrBytesPath | _FileBinaryWrite,
45+
/,
46+
mode: _WriteBinaryMode,
47+
*,
48+
level: int | None = None,
49+
options: Mapping[int, int] | None = None,
50+
zstd_dict: ZstdDict | None = None,
51+
) -> None: ...
52+
def write(self, data: ReadableBuffer, /) -> int: ...
53+
def flush(self, mode: _ZstdCompressorFlushBlock | _ZstdCompressorFlushFrame = 1) -> bytes: ... # type: ignore[override]
54+
def read(self, size: int | None = -1) -> bytes: ...
55+
def read1(self, size: int | None = -1) -> bytes: ...
56+
def readinto(self, b: WriteableBuffer) -> int: ...
57+
def readinto1(self, b: WriteableBuffer) -> int: ...
58+
def readline(self, size: int | None = -1) -> bytes: ...
59+
def seek(self, offset: int, whence: int = 0) -> int: ...
60+
def peek(self, size: int = -1) -> bytes: ...
61+
@property
62+
def name(self) -> str | bytes: ...
63+
@property
64+
def mode(self) -> Literal["rb", "wb"]: ...
65+
66+
@overload
67+
def open(
68+
file: StrOrBytesPath | _FileBinaryRead,
69+
/,
70+
mode: _ReadBinaryMode = "rb",
71+
*,
72+
level: None = None,
73+
options: Mapping[int, int] | None = None,
74+
zstd_dict: ZstdDict | None = None,
75+
encoding: str | None = None,
76+
errors: str | None = None,
77+
newline: str | None = None,
78+
) -> ZstdFile: ...
79+
@overload
80+
def open(
81+
file: StrOrBytesPath | _FileBinaryWrite,
82+
/,
83+
mode: _WriteBinaryMode,
84+
*,
85+
level: int | None = None,
86+
options: Mapping[int, int] | None = None,
87+
zstd_dict: ZstdDict | None = None,
88+
encoding: str | None = None,
89+
errors: str | None = None,
90+
newline: str | None = None,
91+
) -> ZstdFile: ...
92+
@overload
93+
def open(
94+
file: StrOrBytesPath | _WrappedBuffer,
95+
/,
96+
mode: _ReadTextMode,
97+
*,
98+
level: None = None,
99+
options: Mapping[int, int] | None = None,
100+
zstd_dict: ZstdDict | None = None,
101+
encoding: str | None = None,
102+
errors: str | None = None,
103+
newline: str | None = None,
104+
) -> TextIOWrapper: ...
105+
@overload
106+
def open(
107+
file: StrOrBytesPath | _WrappedBuffer,
108+
/,
109+
mode: _WriteTextMode,
110+
*,
111+
level: int | None = None,
112+
options: Mapping[int, int] | None = None,
113+
zstd_dict: ZstdDict | None = None,
114+
encoding: str | None = None,
115+
errors: str | None = None,
116+
newline: str | None = None,
117+
) -> TextIOWrapper: ...

0 commit comments

Comments
 (0)