Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 5 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,15 @@ jobs:
- "3.13"
- "3.14"
- "3.14t"
- "3.15"
- "3.15t"
- "pypy-3.10"
- "pypy-3.11"
os: ["ubuntu-latest"]
include:
- os: "macos-latest" # For m1 macos
python-version: "3.12"
- os: "macos-13" # for x86 macos
- os: "macos-15-intel" # for x86 macos
python-version: "3.10"
- os: "windows-latest"
python-version: "3.10"
Expand Down Expand Up @@ -133,7 +135,7 @@ jobs:
matrix:
os:
- "ubuntu-latest"
- "macos-13"
- "macos-15-intel"
- "macos-latest"
- "windows-latest"
python_version: [ "python" ]
Expand Down Expand Up @@ -171,7 +173,7 @@ jobs:
matrix:
os:
- ubuntu-latest
- macos-13
- macos-15-intel
- macos-latest
- windows-latest
- windows-11-arm
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ Changelog
version 1.0.1-dev
-----------------
+ Wheels are now built for Windows arm64 architectures.
+ 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.

version 1.0.0
-----------------
Expand Down
3 changes: 2 additions & 1 deletion src/zlib_ng/zlib_ngmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,8 @@ zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored))

if (!self->is_initialised) {
PyErr_SetString(PyExc_ValueError, "Cannot copy flushed objects.");
goto error;
Py_DECREF(return_value);
return NULL;
}

/* Copy the zstream state
Expand Down
24 changes: 12 additions & 12 deletions tests/test_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,21 @@ def limited_zlib_tests(strategies=ZLIB_STRATEGIES):


@pytest.mark.parametrize(["data_size", "value"],
itertools.product(DATA_SIZES, SEEDS))
list(itertools.product(DATA_SIZES, SEEDS)))
def test_crc32(data_size, value):
data = DATA[:data_size]
assert zlib.crc32(data, value) == zlib_ng.crc32(data, value)


@pytest.mark.parametrize(["data_size", "value"],
itertools.product(DATA_SIZES, SEEDS))
list(itertools.product(DATA_SIZES, SEEDS)))
def test_adler32(data_size, value):
data = DATA[:data_size]
assert zlib.adler32(data, value) == zlib_ng.adler32(data, value)


@pytest.mark.parametrize(["data_size", "level", "wbits"],
itertools.product(DATA_SIZES, range(10), WBITS_RANGE))
list(itertools.product(DATA_SIZES, range(10), WBITS_RANGE)))
def test_compress(data_size, level, wbits):
data = DATA[:data_size]
compressed = zlib_ng.compress(data, level=level, wbits=wbits)
Expand All @@ -87,7 +87,7 @@ def test_compress(data_size, level, wbits):


@pytest.mark.parametrize(["data_size", "level"],
itertools.product(DATA_SIZES, range(10)))
list(itertools.product(DATA_SIZES, range(10))))
def test_decompress_zlib(data_size, level):
data = DATA[:data_size]
compressed = zlib.compress(data, level=level)
Expand All @@ -96,7 +96,7 @@ def test_decompress_zlib(data_size, level):


@pytest.mark.parametrize(["data_size", "level", "wbits", "memLevel", "strategy"],
limited_zlib_tests(ZLIB_STRATEGIES))
list(limited_zlib_tests(ZLIB_STRATEGIES)))
def test_decompress_wbits(data_size, level, wbits, memLevel, strategy):
data = DATA[:data_size]
compressobj = zlib.compressobj(level=level, wbits=wbits, memLevel=memLevel,
Expand All @@ -107,7 +107,7 @@ def test_decompress_wbits(data_size, level, wbits, memLevel, strategy):


@pytest.mark.parametrize(["data_size", "level", "wbits"],
itertools.product([128 * 1024], range(10), WBITS_RANGE),)
list(itertools.product([128 * 1024], range(10), WBITS_RANGE),))
def test_decompress_zlib_ng(data_size, level, wbits):
data = DATA[:data_size]
compressed = zlib_ng.compress(data, level=level, wbits=wbits)
Expand All @@ -116,7 +116,7 @@ def test_decompress_zlib_ng(data_size, level, wbits):


@pytest.mark.parametrize(["data_size", "level", "wbits", "memLevel", "strategy"],
limited_zlib_tests(ZLIBNG_STRATEGIES))
list(limited_zlib_tests(ZLIBNG_STRATEGIES)))
def test_compress_compressobj(data_size, level, wbits, memLevel, strategy):
data = DATA[:data_size]
compressobj = zlib_ng.compressobj(level=level,
Expand All @@ -129,7 +129,7 @@ def test_compress_compressobj(data_size, level, wbits, memLevel, strategy):


@pytest.mark.parametrize(["data_size", "level", "wbits", "memLevel", "strategy"],
limited_zlib_tests(ZLIB_STRATEGIES))
list(limited_zlib_tests(ZLIB_STRATEGIES)))
def test_decompress_decompressobj(data_size, level, wbits, memLevel, strategy):
data = DATA[:data_size]
compressobj = zlib.compressobj(level=level, wbits=wbits, memLevel=memLevel,
Expand All @@ -151,15 +151,15 @@ def test_decompressobj_unconsumed_tail():


@pytest.mark.parametrize(["data_size", "level"],
itertools.product(DATA_SIZES, range(10)))
list(itertools.product(DATA_SIZES, range(10))))
def test_gzip_ng_compress(data_size, level):
data = DATA[:data_size]
compressed = gzip_ng.compress(data, compresslevel=level)
assert gzip.decompress(compressed) == data


@pytest.mark.parametrize(["data_size", "level"],
itertools.product(DATA_SIZES, range(10)))
list(itertools.product(DATA_SIZES, range(10))))
def test_decompress_gzip(data_size, level):
data = DATA[:data_size]
compressed = gzip.compress(data, compresslevel=level)
Expand All @@ -168,7 +168,7 @@ def test_decompress_gzip(data_size, level):


@pytest.mark.parametrize(["data_size", "level"],
itertools.product(DATA_SIZES, range(10)))
list(itertools.product(DATA_SIZES, range(10))))
def test_decompress_gzip_ng(data_size, level):
data = DATA[:data_size]
compressed = gzip_ng.compress(data, compresslevel=level)
Expand All @@ -177,7 +177,7 @@ def test_decompress_gzip_ng(data_size, level):


@pytest.mark.parametrize(["unused_size", "wbits"],
itertools.product([26], [-15, 15, 31]))
list(itertools.product([26], [-15, 15, 31])))
def test_unused_data(unused_size, wbits):
unused_data = b"abcdefghijklmnopqrstuvwxyz"[:unused_size]
compressor = zlib.compressobj(wbits=wbits)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_gzip_ng.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def test_GzipNGFile_read_truncated():
"reached")


@pytest.mark.parametrize("level", range(1, 10))
@pytest.mark.parametrize("level", list(range(1, 10)))
def test_decompress_stdin_stdout(capsysbinary, level):
"""Test if the command line can decompress data that has been compressed
by gzip at all levels."""
Expand Down
4 changes: 2 additions & 2 deletions tests/test_gzip_ng_threaded.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_threaded_read():


@pytest.mark.parametrize(["mode", "threads"],
itertools.product(["wb", "wt"], [1, 3, -1]))
list(itertools.product(["wb", "wt"], [1, 3, -1])))
def test_threaded_write(mode, threads):
with tempfile.NamedTemporaryFile("wb", delete=False) as tmp:
# Use a small block size to simulate many writes.
Expand Down Expand Up @@ -216,7 +216,7 @@ def test_threaded_writer_does_not_close_stream():

@pytest.mark.timeout(5)
@pytest.mark.parametrize(
["mode", "threads"], itertools.product(["rb", "wb"], [1, 2]))
["mode", "threads"], list(itertools.product(["rb", "wb"], [1, 2])))
def test_threaded_program_can_exit_on_error(tmp_path, mode, threads):
program = tmp_path / "no_context_manager.py"
test_file = tmp_path / "output.gz"
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ setenv=
PYTHONDEVMODE=1
commands =
# Create HTML coverage report for humans and xml coverage report for external services.
coverage run --branch --source=zlib_ng -m pytest tests
coverage run --branch --source=zlib_ng -m pytest {posargs:tests}
# Ignore errors during report generation. Pypy does not generate proper coverage reports.
coverage html -i
coverage xml -i
Expand Down
Loading