Skip to content

Commit d6c0f08

Browse files
bmwiedemannindygreg
authored andcommitted
global: adapt to zstd 1.5.7
All our code changes required to support the upgrade from 1.5.6. * Rust zstd upgraded to 1.5.7 to match C version. * Test output changes. * `zstd_errors.h` inclusion via `zstd.h` caused problems. * MUSL 1.1 compatibility issues (see previous commit).
1 parent cb8fc35 commit d6c0f08

13 files changed

Lines changed: 337 additions & 66 deletions

Cargo.lock

Lines changed: 295 additions & 45 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

c-ext/backend_c.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void zstd_module_init(PyObject *m) {
152152
PyObject *features = NULL;
153153
PyObject *feature = NULL;
154154
unsigned zstd_ver_no = ZSTD_versionNumber();
155-
unsigned our_hardcoded_version = 10506;
155+
unsigned our_hardcoded_version = 10507;
156156
if (ZSTD_VERSION_NUMBER != our_hardcoded_version ||
157157
zstd_ver_no != our_hardcoded_version) {
158158
PyErr_Format(

make_cffi.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
]
2323

2424
# Headers whose preprocessed output will be fed into cdef().
25-
HEADERS = [os.path.join(HERE, "zstd", p) for p in ("zstd.h", "zdict.h")]
25+
HEADERS = [os.path.join(HERE, "zstd", p) for p in ("zstd_errors.h", "zstd.h", "zdict.h")]
2626

2727
INCLUDE_DIRS = [
2828
os.path.join(HERE, "zstd"),
@@ -76,8 +76,8 @@ def preprocess(path):
7676
# boilerplate. This can lead to duplicate declarations. So we strip
7777
# this include from the preprocessor invocation.
7878
#
79-
# The same things happens for including zstd.h, so give it the same
80-
# treatment.
79+
# The same things happens for including zstd.h and zstd_errors.h, so
80+
# give them the same treatment.
8181
#
8282
# We define ZSTD_STATIC_LINKING_ONLY, which is redundant with the inline
8383
# #define in zstdmt_compress.h and results in a compiler warning. So drop
@@ -86,11 +86,17 @@ def preprocess(path):
8686
(
8787
b"#include <stddef.h>",
8888
b'#include "zstd.h"',
89+
b'#include "zstd_errors.h"',
8990
b"#define ZSTD_STATIC_LINKING_ONLY",
9091
)
9192
):
9293
continue
9394

95+
# There's a naked `static` before the declaration of ZSTD_customMem that
96+
# confuses the cffi parser. Strip it.
97+
if line == b'static\n':
98+
continue
99+
94100
# The preprocessor environment on Windows doesn't define include
95101
# paths, so the #include of limits.h fails. We work around this
96102
# by removing that import and defining INT_MAX ourselves. This is
@@ -158,18 +164,18 @@ def normalize_output(output):
158164
return b"\n".join(lines)
159165

160166

167+
168+
161169
ffi = cffi.FFI()
162-
# zstd.h uses a possible undefined MIN(). Define it until
163-
# https://github.com/facebook/zstd/issues/976 is fixed.
164170
# *_DISABLE_DEPRECATE_WARNINGS prevents the compiler from emitting a warning
165171
# when cffi uses the function. Since we statically link against zstd, even
166172
# if we use the deprecated functions it shouldn't be a huge problem.
167173
ffi.set_source(
168174
"zstandard._cffi",
169175
"""
170-
#define MIN(a,b) ((a)<(b) ? (a) : (b))
171176
#define ZSTD_STATIC_LINKING_ONLY
172177
#define ZSTD_DISABLE_DEPRECATE_WARNINGS
178+
#include <zstd_errors.h>
173179
#include <zstd.h>
174180
#define ZDICT_STATIC_LINKING_ONLY
175181
#define ZDICT_DISABLE_DEPRECATE_WARNINGS
@@ -179,7 +185,7 @@ def normalize_output(output):
179185
include_dirs=INCLUDE_DIRS,
180186
)
181187

182-
DEFINE = re.compile(b"^\\#define ([a-zA-Z0-9_]+) ")
188+
DEFINE = re.compile(rb"^#define\s+([a-zA-Z0-9_]+)\s+(\S+)")
183189

184190
sources = []
185191

@@ -204,9 +210,14 @@ def normalize_output(output):
204210
if m.group(1) in (b"ZSTD_LIB_VERSION", b"ZSTD_VERSION_STRING"):
205211
continue
206212

213+
# These defines create aliases from old (camelCase) type names
214+
# to the new PascalCase names, which breaks CFFI.
215+
if m.group(1).lower() == m.group(2).lower():
216+
continue
217+
207218
# The ... is magic syntax by the cdef parser to resolve the
208219
# value at compile time.
209-
sources.append(m.group(0) + b" ...")
220+
sources.append(b"#define " + m.group(1) + b" ...")
210221

211222
cdeflines = b"\n".join(sources).splitlines()
212223
cdeflines = [line for line in cdeflines if line.strip()]

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Documentation = "https://python-zstandard.readthedocs.io/en/latest/"
2828
[build-system]
2929
requires = [
3030
"cffi>=1.17.0",
31+
"packaging",
3132
"setuptools",
3233
]
3334
# Need to use legacy backend because setup_zstd.py breaks build isolation.

rust-ext/src/decompressor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,11 @@ impl ZstdDecompressor {
256256
}
257257

258258
let chunk_buffer: PyBuffer<u8> = PyBuffer::get(&chunk.as_borrowed())?;
259-
let mut params = zstd_sys::ZSTD_frameHeader {
259+
let mut params = zstd_sys::ZSTD_FrameHeader {
260260
frameContentSize: 0,
261261
windowSize: 0,
262262
blockSizeMax: 0,
263-
frameType: zstd_sys::ZSTD_frameType_e::ZSTD_frame,
263+
frameType: zstd_sys::ZSTD_FrameType_e::ZSTD_frame,
264264
headerSize: 0,
265265
dictID: 0,
266266
checksumFlag: 0,

rust-ext/src/frame_parameters.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use {
1212

1313
#[pyclass(module = "zstandard.backend_rust")]
1414
struct FrameParameters {
15-
header: zstd_sys::ZSTD_frameHeader,
15+
header: zstd_sys::ZSTD_FrameHeader,
1616
}
1717

1818
unsafe impl Sync for FrameParameters {}
@@ -75,11 +75,11 @@ fn get_frame_parameters(py: Python, buffer: PyBuffer<u8>) -> PyResult<Py<FramePa
7575
std::slice::from_raw_parts::<u8>(buffer.buf_ptr() as *const _, buffer.len_bytes())
7676
};
7777

78-
let mut header = zstd_sys::ZSTD_frameHeader {
78+
let mut header = zstd_sys::ZSTD_FrameHeader {
7979
frameContentSize: 0,
8080
windowSize: 0,
8181
blockSizeMax: 0,
82-
frameType: zstd_sys::ZSTD_frameType_e::ZSTD_frame,
82+
frameType: zstd_sys::ZSTD_FrameType_e::ZSTD_frame,
8383
headerSize: 0,
8484
dictID: 0,
8585
checksumFlag: 0,

setup_zstd.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import subprocess
1515
import sys
1616

17+
import packaging.tags
18+
1719
ext_includes = [
1820
"c-ext",
1921
]
@@ -89,6 +91,13 @@ def get_c_extension(
8991
if not system_zstd and support_legacy:
9092
extra_args.append("-DZSTD_LEGACY_SUPPORT=1")
9193

94+
# musl 1.1 doesn't define qsort_r. We need to force using the C90
95+
# variant. ZDICT_QSORT officially introduced in 1.5.8. But our
96+
# vendored copy backported to 1.5.7.
97+
for tag in packaging.tags.platform_tags():
98+
if tag.startswith("musllinux_1_1_"):
99+
extra_args.append("-DZDICT_QSORT=ZDICT_QSORT_C90")
100+
92101
if warnings_as_errors:
93102
if compiler_type in ("unix", "mingw32"):
94103
extra_args.append("-Werror")

tests/test_compressor_compress.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_compress_large(self):
5252

5353
cctx = zstd.ZstdCompressor(level=3, write_content_size=False)
5454
result = cctx.compress(b"".join(chunks))
55-
self.assertEqual(len(result), 999)
55+
self.assertEqual(len(result), 1029)
5656
self.assertEqual(result[0:4], b"\x28\xb5\x2f\xfd")
5757

5858
# This matches the test for read_to_iter() below.

tests/test_compressor_compressobj.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_compressobj_large(self):
3939
cobj = cctx.compressobj()
4040

4141
result = cobj.compress(b"".join(chunks)) + cobj.flush()
42-
self.assertEqual(len(result), 999)
42+
self.assertEqual(len(result), 1029)
4343
self.assertEqual(result[0:4], b"\x28\xb5\x2f\xfd")
4444

4545
params = zstd.get_frame_parameters(result)

tests/test_compressor_copy_stream.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def test_large_data(self):
5050
r, w = cctx.copy_stream(source, dest)
5151

5252
self.assertEqual(r, 255 * 16384)
53-
self.assertEqual(w, 999)
53+
self.assertEqual(w, 1029)
5454

5555
params = zstd.get_frame_parameters(dest.getvalue())
5656
self.assertEqual(params.content_size, zstd.CONTENTSIZE_UNKNOWN)

0 commit comments

Comments
 (0)