Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
34c171b
Fix a spelling and copy paste error.
rhpvorderman Sep 15, 2025
07c7f5f
Add windows arm64 wheelbuilding (#73)
finnagin Dec 3, 2025
70dafe5
Re-enable PyPy wheel builds
msto May 20, 2026
10d2ffd
Fix a crash when calling ``copy()`` on a flushed compress object on P…
edgarrmondragon Jul 3, 2026
06bcbef
Fix gzip_ng_threaded writers at level 1 for bytes 144 to 255
ptweezy Oct 20, 2026
42384b1
Raise write errors in gzip_ng_threaded instead of waiting forever
ptweezy Oct 20, 2026
2b00ce1
Merge branch 'develop' into ci/enable-pypy-wheels
rhpvorderman Oct 21, 2026
5064aa4
Merge pull request #79 from msto/ci/enable-pypy-wheels
rhpvorderman Oct 21, 2026
bb8611f
Update to latest actions
rhpvorderman Oct 21, 2026
7b6c2a2
Test CI with supported version 3.11
rhpvorderman Oct 21, 2026
1f3bcfd
Explicitly use python 3.11 for dynamic testing.
rhpvorderman Oct 21, 2026
67cf679
Merge pull request #86 from pycompression/rhpvorderman-patch-1
rhpvorderman Oct 21, 2026
8998171
Use the level 1 output buffer size at every level
ptweezy Oct 21, 2026
c8d73b1
Merge branch 'develop' into threaded-level-1
ptweezy Oct 21, 2026
aeb96be
Merge branch 'develop' into threaded-write-error
ptweezy Oct 21, 2026
9db4612
Merge pull request #85 from ptweezy/threaded-level-1
rhpvorderman Oct 23, 2026
42c6118
Merge pull request #84 from ptweezy/threaded-write-error
rhpvorderman Oct 23, 2026
615081d
Throw an overflowerror on adverserial headers
rhpvorderman Nov 3, 2026
ef02a6e
Merge pull request #87 from pycompression/fixadverserialheader
rhpvorderman Nov 3, 2026
ba99bf9
Update included zlib-ng distribution to 2.3.3.
rhpvorderman Nov 3, 2026
cba2a3e
Use Cmake always
rhpvorderman Nov 3, 2026
2f87f7f
Build macos with make
rhpvorderman Nov 3, 2026
8a6c213
Merge pull request #88 from pycompression/newerzlibng
rhpvorderman Nov 3, 2026
acbc3a5
Publish to PyPI according to PyPA recommended method
rhpvorderman Nov 3, 2026
c1ca45c
Add sanitizer testing
rhpvorderman Nov 3, 2026
1e9f162
Ensure cmake is installed on sanitizer
rhpvorderman Nov 3, 2026
b9fd4b6
Merge pull request #89 from pycompression/newerreleasemethod
rhpvorderman Nov 3, 2026
674f35e
Fix broken pipe error when piping into programs using the CLI.
rhpvorderman Nov 3, 2026
7b5f58a
Merge pull request #90 from pycompression/brokenpipe
rhpvorderman Nov 3, 2026
c55f942
Add cmake to readthedocs.yml
rhpvorderman Nov 3, 2026
a2d2176
Set version to 1.1.0
rhpvorderman Nov 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 134 additions & 45 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
submodules: recursive
- name: Set up Python 3.10
uses: actions/setup-python@v5
- name: Set up Python 3.11
uses: actions/setup-python@v7
with:
python-version: "3.10"
python-version: "3.11"
- name: Install tox
run: pip install tox
- name: Lint
Expand All @@ -36,13 +36,13 @@ jobs:
- twine_check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
submodules: recursive
- name: Set up Python 3.10
uses: actions/setup-python@v5
- name: Set up Python 3.11
uses: actions/setup-python@v7
with:
python-version: "3.10"
python-version: "3.11"
- name: Install tox and upgrade setuptools and pip
run: pip install --upgrade tox setuptools pip
- name: Run tox -e ${{ matrix.tox_env }}
Expand All @@ -53,28 +53,31 @@ jobs:
strategy:
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
- "3.14t"
- "pypy-3.10"
- "3.15"
- "3.15t"
- "pypy-3.11"
- "pypy-3.11"
os: ["ubuntu-latest"]
include:
- os: "macos-latest" # For m1 macos
python-version: "3.12"
- os: "macos-13" # for x86 macos
python-version: "3.10"
- os: "macos-15-intel" # for x86 macos
python-version: "3.11"
- os: "windows-latest"
python-version: "3.10"
python-version: "3.11"
- os: "windows-11-arm"
python-version: "3.11"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
submodules: recursive
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
Expand All @@ -83,23 +86,25 @@ jobs:
- name: Set MSVC developer prompt
uses: ilammy/msvc-dev-cmd@v1
if: runner.os == 'Windows'
with:
arch: ${{ matrix.os == 'windows-11-arm' && 'arm64' || 'x64' }}
- name: Install build dependencies (MacOS)
run: brew install make
if: runner.os == 'macOS'
- name: Run tests
run: tox
- name: Upload coverage report
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v7

test-arch:
if: startsWith(github.ref, 'refs/tags') || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main'
runs-on: "ubuntu-latest"
strategy:
matrix:
python_version:
- "3.10"
- "3.11"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
submodules: recursive
- uses: uraimo/run-on-arch-action@v3
Expand Down Expand Up @@ -129,19 +134,16 @@ jobs:
matrix:
os:
- "ubuntu-latest"
- "macos-13"
- "macos-15-intel"
- "macos-latest"
- "windows-latest"
python_version: [ "python" ]
include:
- os: "ubuntu-latest"
python_version: "pypy"
python_version: [ "python==3.11" ]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
submodules: recursive
- name: Install miniconda.
uses: conda-incubator/setup-miniconda@v3 # https://github.com/conda-incubator/setup-miniconda.
uses: conda-incubator/setup-miniconda@v4 # https://github.com/conda-incubator/setup-miniconda.
with:
channels: conda-forge,defaults
- name: Install requirements (universal)
Expand All @@ -154,7 +156,75 @@ jobs:
env:
PYTHON_ZLIB_NG_LINK_DYNAMIC: True

deploy:
# Run the tests on CPython builds with AddressSanitizer and ThreadSanitizer
# from https://github.com/nascheme/cpython_sanity.
test-sanitizers:
runs-on: ubuntu-latest
# A crash under ThreadSanitizer can hang instead of exiting.
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- sanitizer: address
image: ghcr.io/nascheme/cpython-asan:3.14
# The free-threaded build runs Python threads in parallel.
- sanitizer: thread
image: ghcr.io/nascheme/cpython-tsan:3.14t
container:
image: ${{ matrix.image }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install build dependencies
run: apt-get update && apt-get install -y cmake
- name: Install python-isal with ${{ matrix.sanitizer }} sanitizer
# setuptools-scm needs git, and the container user does not own the
# repository.
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
python -m pip install . pytest pytest-timeout
env:
# The extension modules get -fsanitize from CPython. CFLAGS adds it
# to the C code of ISA-L.
CFLAGS: -fsanitize=${{ matrix.sanitizer }} -fno-omit-frame-pointer -g
- name: Run tests
# Do not set PYTHONDEVMODE. Its debug allocator pads each allocation,
# so AddressSanitizer misses small overflows. --capture=sys prints
# sanitizer reports from C code even when they end the process, and
# -v prints the name of the test before its report.
run: python -m pytest -v tests --capture=sys
env:
# Exit at the first data race. A crash after a race can hang.
TSAN_OPTIONS: halt_on_error=1

make_sdist:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
needs:
- lint
- package-checks
- test-static
- test-dynamic
- test-arch
- test-sanitizers
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # Optional, use if you use setuptools_scm
submodules: true # Optional, use if you have submodules
persist-credentials: false # Highly recommended as a good security practice to not store credentials in disk, unless you need this for your specific use case

- name: Build SDist
run: pipx run build --sdist

- uses: actions/upload-artifact@v4
with:
name: cibw-sdist
path: dist/*.tar.gz

build_wheels:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
runs-on: ${{ matrix.os }}
needs:
Expand All @@ -163,24 +233,26 @@ jobs:
- test-static
- test-dynamic
- test-arch
- test-sanitizers
strategy:
matrix:
os:
- ubuntu-latest
- macos-13
- macos-15-intel
- macos-latest
- windows-latest
- windows-11-arm
cibw_archs_linux: ["x86_64"]
build_sdist: [true]
include:
- os: "ubuntu-latest"
cibw_archs_linux: "aarch64"
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
with:
submodules: recursive
fetch-depth: 0 # Fetch everything to get accurately versioned tag.
- uses: actions/setup-python@v2 # Some issues where caused by higher versions.
- uses: actions/setup-python@v7
name: Install Python
- name: Install cibuildwheel twine build
run: python -m pip install cibuildwheel twine build
Expand All @@ -190,16 +262,19 @@ jobs:
- name: Set MSVC developer prompt
uses: ilammy/msvc-dev-cmd@v1
if: runner.os == 'Windows'
with:
arch: ${{ matrix.os == 'windows-11-arm' && 'arm64' || 'x64' }}
- name: Set up QEMU
if: ${{runner.os == 'Linux' && matrix.cibw_archs_linux == 'aarch64'}}
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4
with:
platforms: arm64
- name: Build wheels
run: cibuildwheel --output-dir dist
env:
CIBW_ENABLE: "pypy"
# Skip 32 bit, macosx_arm64 causes issues on cpython 3.9
CIBW_SKIP: "*-win32 *-manylinux_i686 cp38-macosx_arm64"
CIBW_SKIP: "*-win32 *-manylinux_i686 cp38-macosx_arm64 cp39-win_arm64 cp310-win_arm64"
CIBW_ARCHS_LINUX: ${{ matrix.cibw_archs_linux }}
CIBW_TEST_REQUIRES: "pytest"
# Simple tests that requires the project to be build correctly
Expand Down Expand Up @@ -231,21 +306,35 @@ jobs:
if: ${{runner.os == 'Linux' && matrix.cibw_archs_linux == 'x86_64'}}
run:
python -m build --sdist
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: "dist-${{ runner.os }}-${{ runner.arch }}-${{ matrix.cibw_archs_linux }}"
name: "cibw-${{ runner.os }}-${{ runner.arch }}-${{ matrix.cibw_archs_linux }}"
path: "dist/"
- name: Publish package to TestPyPI
# pypa/gh-action-pypi-publish@master does not work on OSX

upload_to_pypi:
needs: [ build_wheels, make_sdist ]
environment: pypi
permissions:
id-token: write
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
steps:
- uses: actions/download-artifact@v5
with:
pattern: cibw-*
path: dist
merge-multiple: true

- name: Publish to test PyPI
# Alpha, Beta and dev releases contain a - in the tag.
if: contains(github.ref, '-') && startsWith(github.ref, 'refs/tags')
run: twine upload --skip-existing -r testpypi dist/*
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
- name: Publish package to PyPI
if: "contains(github.ref, '-') && startsWith(github.ref, 'refs/tags')"
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
skip-existing: true

- name: Publish to PyPI
if: "!contains(github.ref, '-') && startsWith(github.ref, 'refs/tags')"
run: twine upload --skip-existing dist/*
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip-existing: true
2 changes: 2 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ build:
os: "ubuntu-22.04"
tools:
python: "3"
apt_packages:
- cmake

# Make sure zlib-ng is cloned alongside
submodules:
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@ Changelog
.. This document is user facing. Please word the changes in such a way
.. that users understand how the changes affect the new version.

version 1.1.0
-----------------
+ Update included zlib-ng distribution to 2.3.3.
+ Fix BrokenPipeError when piping ``python -m isal.igzip`` into ``head``,
``less`` or similar programs.
+ Fix ``gzip_ng_threaded`` writers that waited forever when writing to the
underlying file failed, for example, because the disk was full. A later call
to ``write()``, ``flush()``, or ``close()`` raises the error. After an error,
``close()`` no longer closes a file object that you passed to
``gzip_ng_threaded.open``.
+ Wheels are now built for Windows arm64 architectures.
+ Restore PyPy wheel builds.
+ Fix a crash when calling ``copy()`` on a flushed compress object on Python
3.15. Python 3.15 changed
(`gh-134745 <https://github.com/python/cpython/issues/134745/>`__)
``PyThread_release_lock`` to use ``PyMutex`` internally, which now raises a
fatal error when releasing a lock that was never acquired.
+ Fix ``gzip_ng_threaded`` writers at compression level 1, which raised
``OverflowError`` for data that does not compress and consists mostly of
bytes 144 to 255.
+ Extraordinarily large gzip headers with either a very long comment or
filename will now cause an ``OverflowError`` rather than use more and more
memory. The size is limited to the internal buffer size which is currently
set at 512 KiB.

version 1.0.0
-----------------
The library has been running without issues as a dependency in quite a few
Expand Down
5 changes: 1 addition & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,12 @@ def build_zlib_ng():
subprocess.run([os.path.join(build_dir, "configure")], **run_args)
make_program = "gmake" if shutil.which("gmake") else "make"
subprocess.run([make_program, "libz-ng.a"], **run_args)
elif sys.platform == "linux":
subprocess.run([os.path.join(build_dir, "configure")], **run_args)
subprocess.run(["make", "libz-ng.a", "-j", str(cpu_count)], **run_args)
else:
subprocess.run(["cmake", build_dir], **run_args)
# Do not create test suite and do not perform tests to shorten build times.
# There is no need when stable releases of zlib-ng are used.
subprocess.run(["cmake", "--build", build_dir, "--config", "Release",
"--target", "zlibstatic",
"--target", "zlib-ng-static",
"-j", str(cpu_count)], **run_args)
if BUILD_CACHE:
BUILD_CACHE_FILE.write_text(build_dir)
Expand Down
3 changes: 3 additions & 0 deletions src/zlib_ng/gzip_ng.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ def main():
READ_BUFFER_SIZE = args.buffer_size
try:
shutil.copyfileobj(in_file, out_file, args.buffer_size)
except BrokenPipeError:
# Do not throw errors when a pipe to head or less closes.
pass
finally:
if in_file is not sys.stdin.buffer:
in_file.close()
Expand Down
Loading
Loading