Skip to content

Commit de1b55d

Browse files
authored
Merge pull request #130 from pycompression/release_1.1.0
Release 1.1.0
2 parents 9c4a459 + 796ee1e commit de1b55d

File tree

9 files changed

+287
-201
lines changed

9 files changed

+287
-201
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ jobs:
6161
- "3.8"
6262
- "3.9"
6363
- "3.10"
64+
- "3.11-dev"
6465
- "pypy-3.7"
6566
- "pypy-3.8"
6667
- "pypy-3.9"

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ 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 1.1.0
11+
-----------------
12+
+ Added tests and support for Python 3.11.
13+
1014
version 1.0.1
1115
------------------
1216
+ Fixed failing tests and wheel builds for PyPy.

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def build_isa_l(compiler_command: str, compiler_options: str):
161161

162162
setup(
163163
name="isal",
164-
version="1.0.1",
164+
version="1.1.0",
165165
description="Faster zlib and gzip compatible compression and "
166166
"decompression by providing python bindings for the ISA-L "
167167
"library.",
@@ -188,6 +188,7 @@ def build_isa_l(compiler_command: str, compiler_options: str):
188188
"Programming Language :: Python :: 3.8",
189189
"Programming Language :: Python :: 3.9",
190190
"Programming Language :: Python :: 3.10",
191+
"Programming Language :: Python :: 3.11",
191192
"Programming Language :: Python :: Implementation :: CPython",
192193
"Programming Language :: Python :: Implementation :: PyPy",
193194
"Programming Language :: C",

src/isal/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@
2727
"__version__"
2828
]
2929

30-
__version__ = "1.0.1"
30+
__version__ = "1.1.0"

src/isal/_isalmodule.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
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
1+
/*
2+
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3+
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022
4+
Python Software Foundation; All Rights Reserved
45
5-
// This file is part of python-isal which is distributed under the
6-
// PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2.
6+
This file is part of python-isal which is distributed under the
7+
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2.
78
8-
// This file is not originally from the CPython distribution. But it does contain mostly example code
9-
// from the Python docs. Also dual licensing just for this one file seemed silly.
9+
This file is not originally from the CPython distribution. But it does
10+
contain mostly example code from the Python docs. Also dual licensing just
11+
for this one file seemed silly.
12+
*/
1013

1114
#define PY_SSIZE_T_CLEAN
1215
#include <Python.h>
@@ -24,20 +27,19 @@ static struct PyModuleDef _isal_module = {
2427
PyMODINIT_FUNC
2528
PyInit__isal(void)
2629
{
27-
PyObject *m;
28-
29-
m = PyModule_Create(&_isal_module);
30-
if (m == NULL)
30+
PyObject *m = PyModule_Create(&_isal_module);
31+
if (m == NULL) {
3132
return NULL;
32-
33+
}
3334
PyModule_AddIntMacro(m, ISAL_MAJOR_VERSION);
3435
PyModule_AddIntMacro(m, ISAL_MINOR_VERSION);
3536
PyModule_AddIntMacro(m, ISAL_PATCH_VERSION);
3637

3738
PyObject *isal_version = PyUnicode_FromFormat(
3839
"%d.%d.%d", ISAL_MAJOR_VERSION, ISAL_MINOR_VERSION, ISAL_PATCH_VERSION);
39-
if (isal_version == NULL)
40+
if (isal_version == NULL) {
4041
return NULL;
42+
}
4143
PyModule_AddObject(m, "ISAL_VERSION", isal_version);
4244
return m;
4345
}

src/isal/igzip.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def __init__(self, filename=None, mode=None,
167167
0)
168168
if self.mode == READ:
169169
raw = _IGzipReader(self.fileobj)
170-
self._buffer = io.BufferedReader(raw, buffer_size=READ_BUFFER_SIZE)
170+
self._buffer = io.BufferedReader(raw)
171171

172172
def __repr__(self):
173173
s = repr(self.fileobj)

src/isal/igzip_libmodule.c

Lines changed: 68 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,47 @@
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-isal which is distributed under the
6-
// PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2.
7-
8-
// This file was modified from Cpython Modules/bz2module.c file from the 3.9
9-
// branch.
10-
11-
// Changes compared to CPython:
12-
// - The BZ2Decompressor has been used as a basis for IgzipDecompressor.
13-
// Functionality is almost the same. IgzipDecompressor does have a more
14-
// elaborate __init__ to set settings. It also implements decompress_buf more
15-
// akin to how decompression is implemented in isal_shared.h
16-
// - Constants were added that are particular to igzip_lib.
17-
// - Argument parsers were written using th CPython API rather than argument
18-
// clinic.
1+
/*
2+
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3+
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022
4+
Python Software Foundation; All Rights Reserved
5+
6+
This file is part of python-isal which is distributed under the
7+
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2.
8+
9+
This file was modified from Cpython Modules/bz2module.c file from the 3.9
10+
branch.
11+
12+
Changes compared to CPython:
13+
- The BZ2Decompressor has been used as a basis for IgzipDecompressor.
14+
Functionality is almost the same. IgzipDecompressor does have a more
15+
elaborate __init__ to set settings. It also implements decompress_buf more
16+
akin to how decompression is implemented in isal_shared.h
17+
- Constants were added that are particular to igzip_lib.
18+
- Argument parsers were written using th CPython API rather than argument
19+
clinic.
20+
*/
1921

2022
#include "isal_shared.h"
2123

2224
typedef struct {
2325
PyObject_HEAD
24-
struct inflate_state state;
25-
char eof; /* T_BOOL expects a char */
2626
PyObject *unused_data;
2727
PyObject *zdict;
28-
char needs_input;
2928
uint8_t *input_buffer;
3029
Py_ssize_t input_buffer_size;
31-
3230
/* inflate_state>avail_in is only 32 bit, so we store the true length
3331
separately. Conversion and looping is encapsulated in
3432
decompress_buf() */
3533
Py_ssize_t avail_in_real;
34+
char eof; /* T_BOOL expects a char */
35+
char needs_input;
36+
/* Struct inflate state contains a massive buffer at the end. Put it at
37+
the end of the IgzipDecompressor so members can be accessed easily. */
38+
struct inflate_state state;
3639
} IgzipDecompressor;
3740

3841
static void
3942
IgzipDecompressor_dealloc(IgzipDecompressor *self)
4043
{
41-
if(self->input_buffer != NULL)
42-
PyMem_Free(self->input_buffer);
44+
PyMem_Free(self->input_buffer);
4345
Py_CLEAR(self->unused_data);
4446
Py_CLEAR(self->zdict);
4547
Py_TYPE(self)->tp_free((PyObject *)self);
@@ -55,23 +57,23 @@ decompress_buf(IgzipDecompressor *self, Py_ssize_t max_length)
5557
/* data_size is strictly positive, but because we repeatedly have to
5658
compare against max_length and PyBytes_GET_SIZE we declare it as
5759
signed */
58-
PyObject * RetVal = NULL;
60+
PyObject *RetVal = NULL;
5961
Py_ssize_t hard_limit;
6062

6163
Py_ssize_t obuflen;
6264

6365
int err;
6466

65-
// In Python 3.10 sometimes sys.maxsize is passed by default. In those cases
66-
// we do want to use DEF_BUF_SIZE as start buffer.
67+
/* In Python 3.10 sometimes sys.maxsize is passed by default. In those cases
68+
we do want to use DEF_BUF_SIZE as start buffer. */
6769
if ((max_length < 0) || max_length == PY_SSIZE_T_MAX) {
6870
hard_limit = PY_SSIZE_T_MAX;
6971
obuflen = DEF_BUF_SIZE;
7072
} else {
71-
// Assume that decompressor is used in file decompression with a fixed
72-
// block size of max_length. In that case we will reach max_length almost
73-
// always (except at the end of the file). So it makes sense to allocate
74-
// max_length.
73+
/* Assume that decompressor is used in file decompression with a fixed
74+
block size of max_length. In that case we will reach max_length almost
75+
always (except at the end of the file). So it makes sense to allocate
76+
max_length. */
7577
hard_limit = max_length;
7678
obuflen = max_length;
7779
if (obuflen > DEF_MAX_INITIAL_BUF_SIZE){
@@ -102,8 +104,10 @@ decompress_buf(IgzipDecompressor *self, Py_ssize_t max_length)
102104
isal_inflate_error(err);
103105
goto error;
104106
}
105-
} while (self->state.avail_out == 0 && self->state.block_state != ISAL_BLOCK_FINISH);
106-
} while(self->avail_in_real != 0 && self->state.block_state != ISAL_BLOCK_FINISH);
107+
} while (self->state.avail_out == 0 &&
108+
self->state.block_state != ISAL_BLOCK_FINISH);
109+
} while(self->avail_in_real != 0 &&
110+
self->state.block_state != ISAL_BLOCK_FINISH);
107111

108112
if (self->state.block_state == ISAL_BLOCK_FINISH)
109113
self->eof = 1;
@@ -183,13 +187,14 @@ decompress(IgzipDecompressor *self, uint8_t *data, size_t len, Py_ssize_t max_le
183187
self->needs_input = 0;
184188
Py_ssize_t bytes_in_bitbuffer = bitbuffer_size(&(self->state));
185189
if (self->avail_in_real + bytes_in_bitbuffer > 0) {
186-
PyObject * new_data = PyBytes_FromStringAndSize(
190+
PyObject *new_data = PyBytes_FromStringAndSize(
187191
NULL, self->avail_in_real + bytes_in_bitbuffer);
188192
if (new_data == NULL)
189193
goto error;
190-
char * new_data_ptr = PyBytes_AS_STRING(new_data);
194+
char *new_data_ptr = PyBytes_AS_STRING(new_data);
191195
bitbuffer_copy(&(self->state), new_data_ptr, bytes_in_bitbuffer);
192-
memcpy(new_data_ptr + bytes_in_bitbuffer, self->state.next_in, self->avail_in_real);
196+
memcpy(new_data_ptr + bytes_in_bitbuffer, self->state.next_in,
197+
self->avail_in_real);
193198
Py_XSETREF(self->unused_data, new_data);
194199
}
195200
}
@@ -208,7 +213,7 @@ decompress(IgzipDecompressor *self, uint8_t *data, size_t len, Py_ssize_t max_le
208213
/* Discard buffer if it's too small
209214
(resizing it may needlessly copy the current contents) */
210215
if (self->input_buffer != NULL &&
211-
self->input_buffer_size < self->avail_in_real) {
216+
self->input_buffer_size < self->avail_in_real) {
212217
PyMem_Free(self->input_buffer);
213218
self->input_buffer = NULL;
214219
}
@@ -257,13 +262,14 @@ PyDoc_STRVAR(igzip_lib_compress__doc__,
257262
" the header and trailer are controlled by the flag parameter.");
258263

259264
#define IGZIP_LIB_COMPRESS_METHODDEF \
260-
{"compress", (PyCFunction)(void(*)(void))igzip_lib_compress, METH_VARARGS|METH_KEYWORDS, igzip_lib_compress__doc__}
265+
{"compress", (PyCFunction)(void(*)(void))igzip_lib_compress, \
266+
METH_VARARGS|METH_KEYWORDS, igzip_lib_compress__doc__}
261267

262268
static PyObject *
263269
igzip_lib_compress(PyObject *module, PyObject *args, PyObject *kwargs)
264270
{
265-
char *keywords[] = {"", "level", "flag", "mem_level", "hist_bits", NULL};
266-
char *format ="y*|iiii:compress";
271+
static char *keywords[] = {"", "level", "flag", "mem_level", "hist_bits", NULL};
272+
static char *format ="y*|iiii:compress";
267273
Py_buffer data = {NULL, NULL};
268274
int level = ISAL_DEFAULT_COMPRESSION;
269275
int flag = COMP_DEFLATE;
@@ -298,13 +304,14 @@ PyDoc_STRVAR(igzip_lib_decompress__doc__,
298304
" The initial output buffer size.");
299305

300306
#define IGZIP_LIB_DECOMPRESS_METHODDEF \
301-
{"decompress", (PyCFunction)(void(*)(void))igzip_lib_decompress, METH_VARARGS|METH_KEYWORDS, igzip_lib_decompress__doc__}
307+
{"decompress", (PyCFunction)(void(*)(void))igzip_lib_decompress, \
308+
METH_VARARGS|METH_KEYWORDS, igzip_lib_decompress__doc__}
302309

303310
static PyObject *
304311
igzip_lib_decompress(PyObject *module, PyObject *args, PyObject *kwargs)
305312
{
306-
char *keywords[] = {"", "flag", "hist_bits", "bufsize", NULL};
307-
char *format ="y*|iin:decompress";
313+
static char *keywords[] = {"", "flag", "hist_bits", "bufsize", NULL};
314+
static char *format ="y*|iin:decompress";
308315
Py_buffer data = {NULL, NULL};
309316
int flag = DECOMP_DEFLATE;
310317
int hist_bits = ISAL_DEF_MAX_HIST_BITS;
@@ -315,7 +322,7 @@ igzip_lib_decompress(PyObject *module, PyObject *args, PyObject *kwargs)
315322
&data, &flag, &hist_bits, &bufsize)) {
316323
return NULL;
317324
}
318-
PyObject * return_value = igzip_lib_decompress_impl(&data, flag, hist_bits, bufsize);
325+
PyObject *return_value = igzip_lib_decompress_impl(&data, flag, hist_bits, bufsize);
319326
PyBuffer_Release(&data);
320327
return return_value;
321328
}
@@ -340,13 +347,16 @@ PyDoc_STRVAR(igzip_lib_IgzipDecompressor_decompress__doc__,
340347
"the unused_data attribute.");
341348

342349
#define IGZIP_LIB_IGZIPDECOMPRESSOR_DECOMPRESS_METHODDEF \
343-
{"decompress", (PyCFunction)(void(*)(void))igzip_lib_IgzipDecompressor_decompress, METH_VARARGS|METH_KEYWORDS, igzip_lib_IgzipDecompressor_decompress__doc__}
350+
{"decompress", (PyCFunction)(void(*)(void))igzip_lib_IgzipDecompressor_decompress, \
351+
METH_VARARGS|METH_KEYWORDS, igzip_lib_IgzipDecompressor_decompress__doc__}
344352

345353
static PyObject *
346-
igzip_lib_IgzipDecompressor_decompress(IgzipDecompressor *self, PyObject *args, PyObject *kwargs)
354+
igzip_lib_IgzipDecompressor_decompress(IgzipDecompressor *self,
355+
PyObject *args,
356+
PyObject *kwargs)
347357
{
348-
char *keywords[] = {"", "max_length", NULL};
349-
char *format = "y*|n:decompress";
358+
static char *keywords[] = {"", "max_length", NULL};
359+
static char *format = "y*|n:decompress";
350360
Py_buffer data = {NULL, NULL};
351361
Py_ssize_t max_length = -1;
352362

@@ -383,8 +393,8 @@ igzip_lib_IgzipDecompressor__new__(PyTypeObject *type,
383393
PyObject *args,
384394
PyObject *kwargs)
385395
{
386-
char *keywords[] = {"flag", "hist_bits", "zdict", NULL};
387-
char *format = "|iiO:IgzipDecompressor";
396+
static char *keywords[] = {"flag", "hist_bits", "zdict", NULL};
397+
static char *format = "|iiO:IgzipDecompressor";
388398
int flag = ISAL_DEFLATE;
389399
int hist_bits = ISAL_DEF_MAX_HIST_BITS;
390400
PyObject *zdict = NULL;
@@ -458,8 +468,9 @@ static PyMemberDef IgzipDecompressor_members[] = {
458468
READONLY, IgzipDecompressor_unused_data__doc__},
459469
{"needs_input", T_BOOL, offsetof(IgzipDecompressor, needs_input), READONLY,
460470
IgzipDecompressor_needs_input_doc},
461-
{"crc", T_UINT, offsetof(IgzipDecompressor, state) + offsetof(struct inflate_state, crc), READONLY,
462-
IgzipDecompressor_crc_doc},
471+
{"crc", T_UINT,
472+
offsetof(IgzipDecompressor, state) + offsetof(struct inflate_state, crc),
473+
READONLY, IgzipDecompressor_crc_doc},
463474
{NULL}
464475
};
465476

@@ -561,9 +572,7 @@ static struct PyModuleDef igzip_lib_module = {
561572
PyMODINIT_FUNC
562573
PyInit_igzip_lib(void)
563574
{
564-
PyObject *m;
565-
566-
m = PyModule_Create(&igzip_lib_module);
575+
PyObject *m = PyModule_Create(&igzip_lib_module);
567576
if (m == NULL)
568577
return NULL;
569578

@@ -580,10 +589,12 @@ PyInit_igzip_lib(void)
580589
return NULL;
581590
}
582591

583-
if (PyType_Ready(&IgzipDecompressor_Type) != 0)
592+
if (PyType_Ready(&IgzipDecompressor_Type) != 0) {
584593
return NULL;
594+
}
585595
Py_INCREF(&IgzipDecompressor_Type);
586-
if (PyModule_AddObject(m, "IgzipDecompressor", (PyObject *)&IgzipDecompressor_Type) < 0) {
596+
if (PyModule_AddObject(m, "IgzipDecompressor",
597+
(PyObject *)&IgzipDecompressor_Type) < 0) {
587598
return NULL;
588599
}
589600

0 commit comments

Comments
 (0)