zipfile-zstd
zipfile-zstd is a Python library that monkey patches the standard `zipfile` module to enable support for Zstandard compression. It allows both compressing and decompressing files within ZIP archives using the highly efficient Zstandard algorithm. The library is currently at version 0.0.4, with its last release in December 2021, and its primary purpose is to add Zstandard capabilities to Python versions older than 3.14. It relies on the `python-zstandard` library for the underlying Zstandard bindings.
Common errors
-
AttributeError: module 'zipfile' has no attribute 'ZIP_ZSTANDARD'
cause The `zipfile-zstd` monkey-patch was not applied, or the `python-zstandard` dependency is missing, preventing the patch from introducing `ZIP_ZSTANDARD` into the `zipfile` module. This is common when using older Python versions.fixEnsure `import zipfile_zstd` (or `zipfile_zstd.enable_zstandard()`) is called before attempting to use `zipfile.ZIP_ZSTANDARD`. Also, verify that `python-zstandard` is installed via `pip install python-zstandard`. -
ModuleNotFoundError: No module named 'zstandard'
cause The `zipfile-zstd` library depends on `python-zstandard` for its Zstandard bindings, which was not installed.fixInstall the `python-zstandard` package: `pip install python-zstandard`. -
RuntimeError: Compression method 93 is not supported
cause An attempt was made to open or create a Zstandard-compressed ZIP file without the `zipfile` module being correctly patched by `zipfile-zstd`. This means the necessary Zstandard handler is not registered.fixEnsure `import zipfile_zstd` (or `zipfile_zstd.enable_zstandard()`) is executed early in your application before any `zipfile.ZipFile` operations involving Zstandard. Verify `python-zstandard` is installed.
Warnings
- breaking Python 3.14 and newer versions include native Zstandard support in the standard `zipfile` module (via `compression.zstd` and the `zipfile.ZIP_ZSTANDARD` constant). This `zipfile-zstd` package is intended for compatibility with older Python versions (<3.14). Using it on Python 3.14+ might lead to conflicts or be unnecessary.
- gotcha The `zipfile-zstd` library does not support advanced Zstandard compression parameters or dictionaries, which are available in the underlying `python-zstandard` library. It offers only basic Zstandard compression levels.
- gotcha ZIP archives compressed with Zstandard (method ID 93) may not be universally compatible with all ZIP tools, especially older ones (e.g., some versions of Windows Explorer or 7-Zip might require specific forks or updates to handle Zstandard compressed ZIPs).
- gotcha Attempting very high Zstandard compression levels (e.g., 20 or higher) within a ZIP context can lead to 'Out of memory' errors, even for small files, depending on the underlying Zstandard implementation and available system resources.
Install
-
pip install zipfile-zstd python-zstandard
Imports
- zipfile_zstd
import zipfile_zstd
- ZIP_ZSTANDARD
from zipfile import ZIP_ZSTANDARD
from zipfile_zstd import ZIP_ZSTANDARD
Quickstart
import zipfile_zstd
import os
from pathlib import Path
# Enable Zstandard support for the standard zipfile module
zipfile_zstd.enable_zstandard()
# ZIP_ZSTANDARD constant is now available in the patched zipfile module
# or can be imported directly from zipfile_zstd
from zipfile_zstd import ZIP_ZSTANDARD
import zipfile # The standard zipfile module is now patched
archive_name = "example_zstd.zip"
file_to_compress = "test_file.txt"
extracted_dir = "extracted_zstd"
# Create a dummy file for compression
Path(file_to_compress).write_text("This is a test file to be compressed with Zstandard.\n")
try:
# 1. Create a Zstandard compressed ZIP archive
print(f"Creating {archive_name} with Zstandard compression...")
with zipfile.ZipFile(archive_name, 'w', compression=ZIP_ZSTANDARD) as zf:
zf.write(file_to_compress)
print(f"Successfully created {archive_name}.")
# 2. Read and extract from the Zstandard compressed ZIP archive
print(f"Extracting from {archive_name}...")
os.makedirs(extracted_dir, exist_ok=True)
with zipfile.ZipFile(archive_name, 'r') as zf:
zf.extractall(extracted_dir)
print(f"Content extracted to {extracted_dir}.")
# Verify content
extracted_file_path = Path(extracted_dir) / file_to_compress
if extracted_file_path.exists():
print(f"Extracted content: {extracted_file_path.read_text().strip()}")
else:
print("Extraction failed or file not found.")
finally:
# Clean up created files and directories
if Path(file_to_compress).exists():
os.remove(file_to_compress)
if Path(archive_name).exists():
os.remove(archive_name)
if Path(extracted_dir).exists():
import shutil
shutil.rmtree(extracted_dir)
print("Cleanup complete.")