Fast GZIP-to-ZIP/ZIP64 conversion without recompression
Project description
gz2zip
gz2zip converts GZIP to ZIP/ZIP64 without recompression by reusing the original Deflate payload.
This is much faster than decompressing and re-zipping, and it supports both:
- seekable file conversion (
gzip_to_zip) - streaming conversion (
stream_gzip_to_zip) for pipes and async workloads
Benchmark
Benchmark: 100 MiB text, 5 iterations
Platform: macOS 26.0.1 (arm64)
CPU: Apple M1 Pro
Memory: 32.0 GiB
Python: 3.12.0
Input: 100.00 MiB text -> 30.49 MiB gzip
gz2zip.core.gzip_to_zip mean 9.73 ms median 9.69 ms min 9.32 ms max 10.48 ms
python gzip + zipfile mean 3316.88 ms median 3313.52 ms min 3299.16 ms max 3335.05 ms
shell gzip -dc | zip mean 3390.16 ms median 3385.02 ms min 3361.35 ms max 3435.71 ms
See benchmarks/speed_experiment.py for the benchmark script.
Installation
pip install gz2zip
Install as an isolated CLI tool with pipx:
pipx install gz2zip
or with uv:
uv tool install gz2zip
Run without installing globally:
pipx run gz2zip --help
uvx gz2zip --help
Supported Python versions
Based on the official Python version support table, this package targets:
- Python 3.10
- Python 3.11
- Python 3.12
- Python 3.13
- Python 3.14
CLI Usage
The package installs the gz2zip command:
gz2zip INPUT_GZ [-o OUTPUT_ZIP] [-n NAME_IN_ZIP] [-s UNCOMPRESSED_SIZE] [-t ISO_TIMESTAMP] [-q]
Common examples
Convert a file and auto-derive output name (input.gz -> input.zip):
gz2zip input.gz
Set output path and internal filename:
gz2zip input.gz -o output.zip -n data.csv
Pipe from stdin to stdout:
cat input.gz | gz2zip - -n data.csv > output.zip
Large-file case (>4 GiB original content): provide exact uncompressed size:
gz2zip huge.sql.gz -o huge.zip -n huge.sql -s 5368709120
Run as a module:
python -m gz2zip input.gz -o output.zip
CLI options
| Option | Description |
|---|---|
input |
Input .gz file. Use - (or omit) to read from stdin. |
-o, --output |
Output ZIP file. Use - for stdout. |
-n, --name |
Filename to store inside ZIP. |
-s, --size |
Known uncompressed size (recommended for >4 GiB input). |
-t, --timestamp |
Override timestamp in ISO 8601, e.g. 2025-12-31T23:59:58. |
-q, --quiet |
Suppress non-error logs. |
API Usage
Synchronous (seekable files)
from gz2zip import gzip_to_zip
with open("input.gz", "rb") as f_in, open("output.zip", "wb") as f_out:
gzip_to_zip(f_in, f_out, filename_in_zip="data.csv")
Asynchronous streaming
import asyncio
from gz2zip import stream_gzip_to_zip
async def gzip_chunks():
with open("input.gz", "rb") as f:
while chunk := f.read(64 * 1024):
yield chunk
async def main():
with open("output.zip", "wb") as out:
async for chunk in stream_gzip_to_zip(gzip_chunks(), "data.csv"):
out.write(chunk)
asyncio.run(main())
ZIP64 note
GZIP stores ISIZE modulo 2^32, so files larger than 4 GiB need an explicit
known_uncompressed_size (-s in CLI) if exact size metadata is required.
Limitation: concatenated GZIP members
Concatenated GZIP streams are valid (for example: cat a.gz b.gz > joined.gz),
but this project currently does not support that multi-member format
correctly. Use single-member .gz input files.
Development
Run tests:
uv run pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gz2zip-0.1.0.post1.tar.gz.
File metadata
- Download URL: gz2zip-0.1.0.post1.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
938de4cdf5c9ad7a17aa65f1337eedb04c8f7e9ee5585cade433c310264b3460
|
|
| MD5 |
c2ce91efdf93dc245c9eaf08ecbcf079
|
|
| BLAKE2b-256 |
1bfbdd5edb52ebac78ac802cbc755598ce7598b3d51b45dc385127836b45d2a8
|
Provenance
The following attestation bundles were made for gz2zip-0.1.0.post1.tar.gz:
Publisher:
ci.yaml on 45deg/gz2zip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gz2zip-0.1.0.post1.tar.gz -
Subject digest:
938de4cdf5c9ad7a17aa65f1337eedb04c8f7e9ee5585cade433c310264b3460 - Sigstore transparency entry: 1271810768
- Sigstore integration time:
-
Permalink:
45deg/gz2zip@663e32678852662600efd46e2f2fa5d7f6c655d2 -
Branch / Tag:
refs/tags/v0.1.0.post1 - Owner: https://github.com/45deg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yaml@663e32678852662600efd46e2f2fa5d7f6c655d2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file gz2zip-0.1.0.post1-py3-none-any.whl.
File metadata
- Download URL: gz2zip-0.1.0.post1-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aca71cc0b006450c6c96de37941c2923f1afa8514149f643592ee3d6a7bee096
|
|
| MD5 |
61f1a9db0c843d2b4aab354062bc61ae
|
|
| BLAKE2b-256 |
871f99bbc61429082da1902c741362264465da65a99c25377239f103ff799207
|
Provenance
The following attestation bundles were made for gz2zip-0.1.0.post1-py3-none-any.whl:
Publisher:
ci.yaml on 45deg/gz2zip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gz2zip-0.1.0.post1-py3-none-any.whl -
Subject digest:
aca71cc0b006450c6c96de37941c2923f1afa8514149f643592ee3d6a7bee096 - Sigstore transparency entry: 1271810880
- Sigstore integration time:
-
Permalink:
45deg/gz2zip@663e32678852662600efd46e2f2fa5d7f6c655d2 -
Branch / Tag:
refs/tags/v0.1.0.post1 - Owner: https://github.com/45deg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yaml@663e32678852662600efd46e2f2fa5d7f6c655d2 -
Trigger Event:
release
-
Statement type: