Skip to content

Commit ce8a54d

Browse files
authored
Merge pull request #51 from pycompression/release_0.5.0
Release 0.5.0
2 parents 14ca34c + c63960d commit ce8a54d

File tree

10 files changed

+85
-64
lines changed

10 files changed

+85
-64
lines changed

.github/release_checklist.md

-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ Release checklist
22
- [ ] Check outstanding issues on JIRA and Github.
33
- [ ] Check [latest documentation](https://python-zlib-ng.readthedocs.io/en/latest/) looks fine.
44
- [ ] Create a release branch.
5-
- [ ] Set version to a stable number.
65
- [ ] Change current development version in `CHANGELOG.rst` to stable version.
7-
- [ ] Change the version in `__init__.py`
86
- [ ] Merge the release branch into `main`.
97
- [ ] Created an annotated tag with the stable version number. Include changes
108
from CHANGELOG.rst.

.github/workflows/ci.yml

+32-21
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
lint:
1717
runs-on: ubuntu-latest
1818
steps:
19-
- uses: actions/checkout@v2.3.4
19+
- uses: actions/checkout@v4
2020
with:
2121
submodules: recursive
2222
- name: Set up Python 3.8
@@ -36,7 +36,7 @@ jobs:
3636
- twine_check
3737
runs-on: ubuntu-latest
3838
steps:
39-
- uses: actions/checkout@v2.3.4
39+
- uses: actions/checkout@v4
4040
with:
4141
submodules: recursive
4242
- name: Set up Python 3.8
@@ -58,18 +58,19 @@ jobs:
5858
- "3.10"
5959
- "3.11"
6060
- "3.12"
61+
- "3.13-dev"
6162
- "pypy-3.9"
6263
- "pypy-3.10"
6364
os: ["ubuntu-latest"]
6465
include:
6566
- os: "macos-14" # For m1 macos
6667
python-version: "3.12"
67-
- os: "macos-latest" # for x86 macos
68+
- os: "macos-13" # for x86 macos
6869
python-version: "3.8"
6970
- os: "windows-latest"
7071
python-version: "3.8"
7172
steps:
72-
- uses: actions/checkout@v2.3.4
73+
- uses: actions/checkout@v4
7374
with:
7475
submodules: recursive
7576
- name: Set up Python ${{ matrix.python-version }}
@@ -94,22 +95,25 @@ jobs:
9495
runs-on: "ubuntu-latest"
9596
strategy:
9697
matrix:
97-
distro: [ "ubuntu_latest" ]
98-
arch: ["aarch64"]
98+
python_version:
99+
- "3.8"
99100
steps:
100-
- uses: actions/checkout@v2.3.4
101+
- uses: actions/checkout@v4
101102
with:
102103
submodules: recursive
103-
- uses: uraimo/run-on-arch-action@v2.2.0
104+
- uses: uraimo/run-on-arch-action@v2.5.0
104105
name: Build & run test
105106
with:
106-
arch: ${{ matrix.arch }}
107-
distro: ${{ matrix.distro }}
108-
install: |
109-
apt-get update -q -y
110-
apt-get install -q -y python3 python3-pip tox cmake git googletest
111-
run: |
112-
tox
107+
arch: none
108+
distro: none
109+
base_image: "--platform=linux/arm64 quay.io/pypa/manylinux2014_aarch64"
110+
# versioningit needs an accessible git repository but the container
111+
# is run as root, which is different from the repository user.
112+
# use git config to override this.
113+
run: |-
114+
git config --global --add safe.directory $PWD
115+
CFLAGS="-DNDEBUG -g0" python${{matrix.python_version}} -m pip install . pytest
116+
python${{matrix.python_version}} -m pytest tests
113117
114118
# Test if the python-zlib-ng conda package can be build. Which is linked
115119
# dynamically to the conda zlib-ng package.
@@ -122,17 +126,21 @@ jobs:
122126
shell: bash -l {0}
123127
strategy:
124128
matrix:
125-
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
129+
os:
130+
- "ubuntu-latest"
131+
- "macos-13"
132+
- "macos-14"
133+
- "windows-latest"
126134
python_version: [ "python" ]
127135
include:
128136
- os: "ubuntu-latest"
129137
python_version: "pypy"
130138
steps:
131-
- uses: actions/checkout@v2.3.4
139+
- uses: actions/checkout@v4
132140
with:
133141
submodules: recursive
134142
- name: Install miniconda.
135-
uses: conda-incubator/setup-miniconda@v2.0.1 # https://github.com/conda-incubator/setup-miniconda.
143+
uses: conda-incubator/setup-miniconda@v3 # https://github.com/conda-incubator/setup-miniconda.
136144
with:
137145
channels: conda-forge,defaults
138146
- name: Install requirements (universal)
@@ -158,17 +166,19 @@ jobs:
158166
matrix:
159167
os:
160168
- ubuntu-latest
161-
- macos-latest
169+
- macos-13
170+
- macos-14
162171
- windows-latest
163172
cibw_archs_linux: ["x86_64"]
164173
build_sdist: [true]
165174
include:
166175
- os: "ubuntu-latest"
167176
cibw_archs_linux: "aarch64"
168177
steps:
169-
- uses: actions/checkout@v2.3.4
178+
- uses: actions/checkout@v4
170179
with:
171180
submodules: recursive
181+
fetch-depth: 0 # Fetch everything to get accurately versioned tag.
172182
- uses: actions/setup-python@v2
173183
name: Install Python
174184
- name: Install cibuildwheel twine build
@@ -187,7 +197,8 @@ jobs:
187197
- name: Build wheels
188198
run: cibuildwheel --output-dir dist
189199
env:
190-
CIBW_SKIP: "*-win32 *-manylinux_i686" # Skip 32 bit
200+
# Skip 32 bit, macosx_arm64 causes issues on cpython 3.8
201+
CIBW_SKIP: "*-win32 *-manylinux_i686 cp38-macosx_arm64"
191202
CIBW_ARCHS_LINUX: ${{ matrix.cibw_archs_linux }}
192203
CIBW_TEST_REQUIRES: "pytest"
193204
# Simple tests that requires the project to be build correctly

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
src/zlib_ng/_version.py
2+
13
# Byte-compiled / optimized / DLL files
24
__pycache__/
35
*.py[cod]

CHANGELOG.rst

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ Changelog
77
.. This document is user facing. Please word the changes in such a way
88
.. that users understand how the changes affect the new version.
99
10+
version 0.5.0
11+
-----------------
12+
+ Wheels are now build for MacOS arm64 architectures.
13+
+ Fix a bug where READ and WRITE in zlib_ng.gzip_ng were inconsistent with the
14+
values in gzip on Python 3.13
15+
+ Small simplifications to the ``gzip_ng.compress`` and ``gzip_ng.decompress``
16+
functions, which should lead to less overhead.
17+
1018
version 0.4.3
1119
-----------------
1220
+ Fix a bug where files larger than 4GB could not be decompressed.

MANIFEST.in

+9
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
11
graft src/zlib_ng/zlib-ng
2+
prune tests
3+
prune docs
4+
prune benchmark_scripts
5+
prune .github
6+
exclude tox.ini
7+
exclude requirements-docs.txt
8+
exclude codecov.yml
9+
exclude .readthedocs.yml
10+
exclude .git*

pyproject.toml

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
[build-system]
2-
requires = ["setuptools>=51", "wheel"]
2+
requires = ["setuptools>=64", "versioningit>=1.1.0"]
33
build-backend = "setuptools.build_meta"
4+
5+
[tool.versioningit.vcs]
6+
method="git"
7+
default-tag = "v0.0.0"
8+
9+
[tool.versioningit.write]
10+
file = "src/zlib_ng/_version.py"

setup.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from setuptools import Extension, find_packages, setup
1717
from setuptools.command.build_ext import build_ext
1818

19+
import versioningit
20+
1921
ZLIB_NG_SOURCE = os.path.join("src", "zlib_ng", "zlib-ng")
2022

2123
SYSTEM_IS_UNIX = (sys.platform.startswith("linux") or
@@ -124,7 +126,7 @@ def build_zlib_ng():
124126

125127
setup(
126128
name="zlib-ng",
127-
version="0.4.3",
129+
version=versioningit.get_version(),
128130
description="Drop-in replacement for zlib and gzip modules using zlib-ng",
129131
author="Leiden University Medical Center",
130132
author_email="[email protected]", # A placeholder for now

src/zlib_ng/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55
# This file is part of python-zlib-ng which is distributed under the
66
# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2.
77

8-
__version__ = "0.4.3"
8+
from ._version import __version__
9+
10+
__all__ = ["__version__"]

src/zlib_ng/_version.pyi

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2+
# 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022
3+
# Python Software Foundation; All Rights Reserved
4+
5+
# This file is part of python-zlib-ng which is distributed under the
6+
# PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2.
7+
8+
__version__: int

src/zlib_ng/gzip_ng.py

+12-38
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import gzip
2323
import io
2424
import os
25+
import shutil
2526
import struct
2627
import sys
2728
import time
@@ -41,7 +42,7 @@
4142
READ_BUFFER_SIZE = 512 * 1024
4243

4344
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
44-
READ, WRITE = 1, 2
45+
READ, WRITE = gzip.READ, gzip.WRITE
4546

4647
BadGzipFile = gzip.BadGzipFile # type: ignore
4748

@@ -180,50 +181,27 @@ def write(self, data):
180181
_GzipNGReader = _GzipReader
181182

182183

183-
def _create_simple_gzip_header(compresslevel: int,
184-
mtime=None) -> bytes:
185-
"""
186-
Write a simple gzip header with no extra fields.
187-
:param compresslevel: Compresslevel used to determine the xfl bytes.
188-
:param mtime: The mtime (must support conversion to a 32-bit integer).
189-
:return: A bytes object representing the gzip header.
190-
"""
191-
if mtime is None:
192-
mtime = time.time()
193-
if compresslevel == _COMPRESS_LEVEL_BEST:
194-
xfl = 2
195-
elif compresslevel == _COMPRESS_LEVEL_FAST:
196-
xfl = 4
197-
else:
198-
xfl = 0
199-
# Pack ID1 and ID2 magic bytes, method (8=deflate), header flags (no extra
200-
# fields added to header), mtime, xfl and os (255 for unknown OS).
201-
return struct.pack("<BBBBLBB", 0x1f, 0x8b, 8, 0, int(mtime), xfl, 255)
202-
203-
204184
def compress(data, compresslevel=_COMPRESS_LEVEL_BEST, *, mtime=None):
205185
"""Compress data in one shot and return the compressed string.
206186
compresslevel sets the compression level in range of 0-9.
207187
mtime can be used to set the modification time. The modification time is
208188
set to the current time by default.
209189
"""
210-
if mtime == 0:
211-
# Use zlib as it creates the header with 0 mtime by default.
212-
# This is faster and with less overhead.
213-
return zlib_ng.compress(data, level=compresslevel, wbits=31)
214-
header = _create_simple_gzip_header(compresslevel, mtime)
215-
trailer = struct.pack("<LL", zlib_ng.crc32(data), (len(data) & 0xffffffff))
216-
# Wbits=-15 creates a raw deflate block.
217-
return (header + zlib_ng.compress(data, level=compresslevel, wbits=-15) +
218-
trailer)
190+
# Wbits=31 automatically includes a gzip header and trailer.
191+
gzip_data = zlib_ng.compress(data, level=compresslevel, wbits=31)
192+
if mtime is None:
193+
mtime = time.time()
194+
# Reuse gzip header created by zlib_ng, replace mtime and OS byte for
195+
# consistency.
196+
header = struct.pack("<4sLBB", gzip_data, int(mtime), gzip_data[8], 255)
197+
return header + gzip_data[10:]
219198

220199

221200
def decompress(data):
222201
"""Decompress a gzip compressed string in one shot.
223202
Return the decompressed string.
224203
"""
225-
fp = io.BytesIO(data)
226-
reader = _GzipReader(fp, max(len(data), 16))
204+
reader = _GzipReader(data)
227205
return reader.readall()
228206

229207

@@ -325,11 +303,7 @@ def main():
325303
global READ_BUFFER_SIZE
326304
READ_BUFFER_SIZE = args.buffer_size
327305
try:
328-
while True:
329-
block = in_file.read(args.buffer_size)
330-
if block == b"":
331-
break
332-
out_file.write(block)
306+
shutil.copyfileobj(in_file, out_file, args.buffer_size)
333307
finally:
334308
if in_file is not sys.stdin.buffer:
335309
in_file.close()

0 commit comments

Comments
 (0)