Skip to content

Commit a8bb7dc

Browse files
authored
feat: add zstd compression module for Python 3.14+ (#1866)
1 parent 0483a51 commit a8bb7dc

File tree

4 files changed

+79
-6
lines changed

4 files changed

+79
-6
lines changed

docker/Dockerfile

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,28 @@ RUN --mount=type=bind,from=static_clang,target=/tmp/cross-compiler,ro \
135135
FROM build_base AS build_mpdecimal
136136
COPY build_scripts/build-mpdecimal.sh /build_scripts/
137137
RUN --mount=type=bind,from=static_clang,target=/tmp/cross-compiler,ro \
138-
export MPDECIMAL_ROOT=mpdecimal-4.0.0 && \
139-
export MPDECIMAL_HASH=942445c3245b22730fd41a67a7c5c231d11cb1b9936b9c0f76334fb7d0b4468c && \
138+
export MPDECIMAL_ROOT=mpdecimal-4.0.1 && \
139+
export MPDECIMAL_HASH=96d33abb4bb0070c7be0fed4246cd38416188325f820468214471938545b1ac8 && \
140140
export MPDECIMAL_DOWNLOAD_URL=https://www.bytereef.org/software/mpdecimal/releases && \
141141
/tmp/cross-compiler/entrypoint /build_scripts/build-mpdecimal.sh
142142

143143

144+
FROM build_base AS build_zstd
145+
COPY build_scripts/build-zstd.sh /build_scripts/
146+
RUN --mount=type=bind,from=static_clang,target=/tmp/cross-compiler,ro \
147+
export ZSTD_VERSION=1.5.7 && \
148+
export ZSTD_HASH=eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 && \
149+
export ZSTD_DOWNLOAD_URL=https://github.com/facebook/zstd/releases/download && \
150+
/tmp/cross-compiler/entrypoint /build_scripts/build-zstd.sh
151+
152+
144153
FROM --platform=${BUILDPLATFORM} ghcr.io/sigstore/cosign/cosign:v${MANYLINUX_COSIGN_VERSION} AS cosign-bin
145154

146155

147156
FROM build_base AS build_cpython
148157
COPY --from=build_tcl_tk /manylinux-buildfs /
149158
COPY --from=build_mpdecimal /manylinux-buildfs /
159+
COPY --from=build_zstd /manylinux-buildfs /
150160
COPY --from=build_sqlite3 /manylinux-buildfs /
151161
RUN if command -v apk >/dev/null 2>&1; then ldconfig /; else ldconfig; fi
152162
COPY build_scripts/build-openssl.sh /build_scripts/
@@ -208,6 +218,7 @@ RUN --mount=type=bind,from=static_clang,target=/tmp/cross-compiler,ro \
208218
FROM runtime_base
209219
COPY --from=build_tcl_tk /manylinux-rootfs /
210220
COPY --from=build_mpdecimal /manylinux-rootfs /
221+
COPY --from=build_zstd /manylinux-rootfs /
211222
COPY --from=build_sqlite3 /manylinux-rootfs /
212223
COPY --from=build_git /manylinux-rootfs /
213224
COPY build_scripts /opt/_internal/build_scripts/
@@ -221,7 +232,8 @@ RUN --mount=type=bind,target=/build_cpython38,from=build_cpython38 \
221232
--mount=type=bind,target=/build_cpython314,from=build_cpython314 \
222233
--mount=type=bind,target=/build_cpython314_nogil,from=build_cpython314_nogil \
223234
mkdir -p /opt/_internal && \
224-
cp -rf /build_cpython*/opt/_internal/* /opt/_internal/ && \
235+
cp -rf /build_cpython*/opt/_internal/cpython* /opt/_internal/ && \
236+
if test -n "$(find /build_cpython314/opt/_internal -maxdepth 1 -name 'openssl*' -print -quit)"; then cp -rf /build_cpython314/opt/_internal/openssl* /opt/_internal/; fi && \
225237
manylinux-entrypoint /opt/_internal/build_scripts/finalize.sh \
226238
pp311-pypy311_pp73
227239

docker/build_scripts/build-zstd.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/bin/bash
2+
# Top-level build script called from Dockerfile
3+
4+
# Stop at any error, show all commands
5+
set -exuo pipefail
6+
7+
# Get script directory
8+
MY_DIR=$(dirname "${BASH_SOURCE[0]}")
9+
10+
# Get build utilities
11+
# shellcheck source-path=SCRIPTDIR
12+
source "${MY_DIR}/build_utils.sh"
13+
14+
# Install a more recent mpdecimal
15+
check_var "${ZSTD_VERSION}"
16+
check_var "${ZSTD_HASH}"
17+
check_var "${ZSTD_DOWNLOAD_URL}"
18+
ZSTD_ROOT="zstd-${ZSTD_VERSION}"
19+
20+
PREFIX=/opt/_internal/${ZSTD_ROOT%%.*}
21+
22+
fetch_source "${ZSTD_ROOT}.tar.gz" "${ZSTD_DOWNLOAD_URL}/v${ZSTD_VERSION}"
23+
check_sha256sum "${ZSTD_ROOT}.tar.gz" "${ZSTD_HASH}"
24+
tar xfz "${ZSTD_ROOT}.tar.gz"
25+
pushd "${ZSTD_ROOT}/lib"
26+
# add rpath
27+
sed -i "s|^Libs:|Libs: -Wl,--enable-new-dtags,-rpath=\${libdir} |g" ./libzstd.pc.in
28+
DESTDIR=/manylinux-rootfs MT=1 prefix=${PREFIX} make install-includes install-pc install-shared V=1 CPPFLAGS="${MANYLINUX_CPPFLAGS} -DZSTD_MULTITHREAD" CFLAGS="${MANYLINUX_CFLAGS} -DZSTD_MULTITHREAD -pthread -fPIC -fvisibility=hidden" LDFLAGS="${MANYLINUX_LDFLAGS} -shared -pthread"
29+
popd
30+
rm -rf "${ZSTD_ROOT}" "${ZSTD_ROOT}.tar.gz"
31+
32+
# Strip what we can
33+
strip_ /manylinux-rootfs
34+
35+
# Install for build
36+
mkdir /manylinux-buildfs
37+
cp -rlf /manylinux-rootfs/* /manylinux-buildfs/
38+
# copy pkgconfig
39+
mkdir -p /manylinux-buildfs/usr/local/lib/pkgconfig/
40+
ln -s "${PREFIX}/lib/pkgconfig/libzstd.pc" /manylinux-buildfs/usr/local/lib/pkgconfig/libzstd.pc
41+
42+
# Clean-up for runtime
43+
rm -rf "/manylinux-rootfs/${PREFIX}/lib/pkgconfig" "/manylinux-rootfs/${PREFIX}/include"

docker/tests/modules-check.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ def test_sysconfig(self):
6262
assert config_vars["LDSHARED"] == f"{cc} -shared", config_vars["LDSHARED"]
6363
assert config_vars["LDCXXSHARED"] == f"{cxx} -shared", config_vars["LDCXXSHARED"]
6464

65+
@unittest.skipIf(sys.version_info[:2] < (3, 14), reason="not supported in this version")
66+
def test_zstd(self):
67+
from compression import zstd
68+
69+
print(f"{zstd.zstd_version_info=}", end=" ", file=sys.stderr)
70+
assert zstd.zstd_version_info[:3] >= (1, 5, 7)
71+
72+
def test_ssl(self):
73+
import ssl
74+
75+
print(f"{ssl.OPENSSL_VERSION_INFO=}", end=" ", file=sys.stderr)
76+
assert ssl.OPENSSL_VERSION_INFO[:3] >= (1, 1, 1)
77+
6578

6679
if __name__ == "__main__":
6780
unittest.main(verbosity=2)

tools/update_native_dependencies.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ def _update_sqlite(dry_run):
145145
def _update_with_gh(tool, dry_run):
146146
repo = {
147147
"libxcrypt": "besser82/libxcrypt",
148+
"zstd": "facebook/zstd",
149+
}
150+
extension = {
151+
"libxcrypt": "tar.xz",
152+
"zstd": "tar.gz",
148153
}
149154
lines = DOCKERFILE.read_text().splitlines()
150155
re_ = re.compile(f"^ export {tool.upper()}_VERSION=(?P<version>\\S+) && \\\\$")
@@ -153,13 +158,13 @@ def _update_with_gh(tool, dry_run):
153158
if match is None:
154159
continue
155160
current_version = Version(match["version"])
156-
latest_tag = latest(repo[tool], output_format="tag")
161+
latest_tag = latest(repo[tool], output_format="tag", having_asset=True)
157162
latest_version = Version(latest_tag)
158163
if latest_version > current_version:
159164
url = re.match(
160165
f"^ export {tool.upper()}_DOWNLOAD_URL=(?P<url>\\S+) && \\\\$", lines[i + 2]
161166
)["url"]
162-
sha256 = _sha256(f"{url}/{latest_tag}/libxcrypt-{latest_version}.tar.xz")
167+
sha256 = _sha256(f"{url}/{latest_tag}/{tool}-{latest_version}.{extension[tool]}")
163168
lines[i + 0] = f" export {tool.upper()}_VERSION={latest_version} && \\"
164169
lines[i + 1] = f" export {tool.upper()}_HASH={sha256} && \\"
165170
message = f"Bump {tool} {current_version}{latest_version}"
@@ -257,7 +262,7 @@ def main():
257262
_update_with_root(tool, args.dry_run)
258263
except Exception as e:
259264
print(f"::warning::update: {e}\n", file=sys.stderr)
260-
for tool in ["libxcrypt"]:
265+
for tool in ["libxcrypt", "zstd"]:
261266
try:
262267
_update_with_gh(tool, args.dry_run)
263268
except Exception as e:

0 commit comments

Comments
 (0)