summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorZackery Spytz <zspytz@gmail.com>2023-02-23 14:00:58 (GMT)
committerGitHub <noreply@github.com>2023-02-23 14:00:58 (GMT)
commit665730d2176aabd05ca5741056aef43189b6f754 (patch)
treea91cd6c443b91d26f5f404629e265aefec8832c1 /Modules
parent9bba8035bd99813203cb3b0de218f9cc3bcdaf2f (diff)
downloadcpython-665730d2176aabd05ca5741056aef43189b6f754.zip
cpython-665730d2176aabd05ca5741056aef43189b6f754.tar.gz
cpython-665730d2176aabd05ca5741056aef43189b6f754.tar.bz2
bpo-23224: Fix segfaults and multiple leaks in the lzma and bz2 modules (GH-7822)
lzma.LZMADecompressor and bz2.BZ2Decompressor objects caused segfaults when their `__init__()` methods were not called. lzma.LZMADecompressor, lzma.LZMACompressor, bz2.BZ2Compressor, and bz2.BZ2Decompressor objects would leak locks and internal buffers when their `__init__()` methods were called multiple times. https://bugs.python.org/issue23224
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_bz2module.c230
-rw-r--r--Modules/_lzmamodule.c126
-rw-r--r--Modules/clinic/_bz2module.c.h75
-rw-r--r--Modules/clinic/_lzmamodule.c.h18
4 files changed, 274 insertions, 175 deletions
diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c
index 9304c13..8e7b8e8 100644
--- a/Modules/_bz2module.c
+++ b/Modules/_bz2module.c
@@ -15,6 +15,29 @@
#error "The maximum block size accepted by libbzip2 is UINT32_MAX."
#endif
+typedef struct {
+ PyTypeObject *bz2_compressor_type;
+ PyTypeObject *bz2_decompressor_type;
+} _bz2_state;
+
+static inline _bz2_state *
+get_module_state(PyObject *module)
+{
+ void *state = PyModule_GetState(module);
+ assert(state != NULL);
+ return (_bz2_state *)state;
+}
+
+static struct PyModuleDef _bz2module;
+
+static inline _bz2_state *
+find_module_state_by_def(PyTypeObject *type)
+{
+ PyObject *module = PyType_GetModuleByDef(type, &_bz2module);
+ assert(module != NULL);
+ return get_module_state(module);
+}
+
/* On success, return value >= 0
On failure, return -1 */
static inline Py_ssize_t
@@ -214,12 +237,14 @@ error:
/*[clinic input]
module _bz2
-class _bz2.BZ2Compressor "BZ2Compressor *" "&BZ2Compressor_Type"
-class _bz2.BZ2Decompressor "BZ2Decompressor *" "&BZ2Decompressor_Type"
+class _bz2.BZ2Compressor "BZ2Compressor *" "clinic_state()->bz2_compressor_type"
+class _bz2.BZ2Decompressor "BZ2Decompressor *" "clinic_state()->bz2_decompressor_type"
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=dc7d7992a79f9cb7]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92348121632b94c4]*/
+#define clinic_state() (find_module_state_by_def(type))
#include "clinic/_bz2module.c.h"
+#undef clinic_state
/*[clinic input]
_bz2.BZ2Compressor.compress
@@ -295,24 +320,43 @@ BZ2_Free(void* ctx, void *ptr)
PyMem_RawFree(ptr);
}
+/*[clinic input]
+@classmethod
+_bz2.BZ2Compressor.__new__
+
+ compresslevel: int = 9
+ Compression level, as a number between 1 and 9.
+ /
-/* Argument Clinic is not used since the Argument Clinic always want to
- check the type which would be wrong here */
-static int
-_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel)
+Create a compressor object for compressing data incrementally.
+
+For one-shot compression, use the compress() function instead.
+[clinic start generated code]*/
+
+static PyObject *
+_bz2_BZ2Compressor_impl(PyTypeObject *type, int compresslevel)
+/*[clinic end generated code: output=83346c96beaacad7 input=d4500d2a52c8b263]*/
{
int bzerror;
+ BZ2Compressor *self;
if (!(1 <= compresslevel && compresslevel <= 9)) {
PyErr_SetString(PyExc_ValueError,
"compresslevel must be between 1 and 9");
- return -1;
+ return NULL;
+ }
+
+ assert(type != NULL && type->tp_alloc != NULL);
+ self = (BZ2Compressor *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
}
self->lock = PyThread_allocate_lock();
if (self->lock == NULL) {
+ Py_DECREF(self);
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
- return -1;
+ return NULL;
}
self->bzs.opaque = NULL;
@@ -322,49 +366,11 @@ _bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel)
if (catch_bz2_error(bzerror))
goto error;
- return 0;
+ return (PyObject *)self;
error:
- PyThread_free_lock(self->lock);
- self->lock = NULL;
- return -1;
-}
-
-PyDoc_STRVAR(_bz2_BZ2Compressor___init____doc__,
-"BZ2Compressor(compresslevel=9, /)\n"
-"--\n"
-"\n"
-"Create a compressor object for compressing data incrementally.\n"
-"\n"
-" compresslevel\n"
-" Compression level, as a number between 1 and 9.\n"
-"\n"
-"For one-shot compression, use the compress() function instead.");
-
-static int
-_bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- int return_value = -1;
- int compresslevel = 9;
-
- if (!_PyArg_NoKeywords("BZ2Compressor", kwargs)) {
- goto exit;
- }
- if (!_PyArg_CheckPositional("BZ2Compressor", PyTuple_GET_SIZE(args), 0, 1)) {
- goto exit;
- }
- if (PyTuple_GET_SIZE(args) < 1) {
- goto skip_optional;
- }
- compresslevel = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0));
- if (compresslevel == -1 && PyErr_Occurred()) {
- goto exit;
- }
-skip_optional:
- return_value = _bz2_BZ2Compressor___init___impl((BZ2Compressor *)self, compresslevel);
-
-exit:
- return return_value;
+ Py_DECREF(self);
+ return NULL;
}
static void
@@ -395,9 +401,8 @@ static PyMethodDef BZ2Compressor_methods[] = {
static PyType_Slot bz2_compressor_type_slots[] = {
{Py_tp_dealloc, BZ2Compressor_dealloc},
{Py_tp_methods, BZ2Compressor_methods},
- {Py_tp_init, _bz2_BZ2Compressor___init__},
- {Py_tp_new, PyType_GenericNew},
- {Py_tp_doc, (char *)_bz2_BZ2Compressor___init____doc__},
+ {Py_tp_new, _bz2_BZ2Compressor},
+ {Py_tp_doc, (char *)_bz2_BZ2Compressor__doc__},
{Py_tp_traverse, BZ2Compressor_traverse},
{0, 0}
};
@@ -624,28 +629,40 @@ _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data,
return result;
}
-/* Argument Clinic is not used since the Argument Clinic always want to
- check the type which would be wrong here */
-static int
-_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self)
+/*[clinic input]
+@classmethod
+_bz2.BZ2Decompressor.__new__
+
+Create a decompressor object for decompressing data incrementally.
+
+For one-shot decompression, use the decompress() function instead.
+[clinic start generated code]*/
+
+static PyObject *
+_bz2_BZ2Decompressor_impl(PyTypeObject *type)
+/*[clinic end generated code: output=5150d51ccaab220e input=b87413ce51853528]*/
{
+ BZ2Decompressor *self;
int bzerror;
- PyThread_type_lock lock = PyThread_allocate_lock();
- if (lock == NULL) {
- PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
- return -1;
+ assert(type != NULL && type->tp_alloc != NULL);
+ self = (BZ2Decompressor *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
}
- if (self->lock != NULL) {
- PyThread_free_lock(self->lock);
+
+ self->lock = PyThread_allocate_lock();
+ if (self->lock == NULL) {
+ Py_DECREF(self);
+ PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
+ return NULL;
}
- self->lock = lock;
self->needs_input = 1;
self->bzs_avail_in_real = 0;
self->input_buffer = NULL;
self->input_buffer_size = 0;
- Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0));
+ self->unused_data = PyBytes_FromStringAndSize(NULL, 0);
if (self->unused_data == NULL)
goto error;
@@ -653,40 +670,13 @@ _bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self)
if (catch_bz2_error(bzerror))
goto error;
- return 0;
+ return (PyObject *)self;
error:
- Py_CLEAR(self->unused_data);
- PyThread_free_lock(self->lock);
- self->lock = NULL;
- return -1;
-}
-
-static int
-_bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- int return_value = -1;
-
- if (!_PyArg_NoPositional("BZ2Decompressor", args)) {
- goto exit;
- }
- if (!_PyArg_NoKeywords("BZ2Decompressor", kwargs)) {
- goto exit;
- }
- return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self);
-
-exit:
- return return_value;
+ Py_DECREF(self);
+ return NULL;
}
-PyDoc_STRVAR(_bz2_BZ2Decompressor___init____doc__,
-"BZ2Decompressor()\n"
-"--\n"
-"\n"
-"Create a decompressor object for decompressing data incrementally.\n"
-"\n"
-"For one-shot decompression, use the decompress() function instead.");
-
static void
BZ2Decompressor_dealloc(BZ2Decompressor *self)
{
@@ -738,10 +728,9 @@ static PyMemberDef BZ2Decompressor_members[] = {
static PyType_Slot bz2_decompressor_type_slots[] = {
{Py_tp_dealloc, BZ2Decompressor_dealloc},
{Py_tp_methods, BZ2Decompressor_methods},
- {Py_tp_init, _bz2_BZ2Decompressor___init__},
- {Py_tp_doc, (char *)_bz2_BZ2Decompressor___init____doc__},
+ {Py_tp_doc, (char *)_bz2_BZ2Decompressor__doc__},
{Py_tp_members, BZ2Decompressor_members},
- {Py_tp_new, PyType_GenericNew},
+ {Py_tp_new, _bz2_BZ2Decompressor},
{Py_tp_traverse, BZ2Decompressor_traverse},
{0, 0}
};
@@ -762,31 +751,52 @@ static PyType_Spec bz2_decompressor_type_spec = {
static int
_bz2_exec(PyObject *module)
{
- PyTypeObject *bz2_compressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
+ _bz2_state *state = get_module_state(module);
+ state->bz2_compressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
&bz2_compressor_type_spec, NULL);
- if (bz2_compressor_type == NULL) {
+ if (state->bz2_compressor_type == NULL) {
return -1;
}
- int rc = PyModule_AddType(module, bz2_compressor_type);
- Py_DECREF(bz2_compressor_type);
- if (rc < 0) {
+ if (PyModule_AddType(module, state->bz2_compressor_type) < 0) {
return -1;
}
- PyTypeObject *bz2_decompressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
+ state->bz2_decompressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module,
&bz2_decompressor_type_spec, NULL);
- if (bz2_decompressor_type == NULL) {
+ if (state->bz2_decompressor_type == NULL) {
return -1;
}
- rc = PyModule_AddType(module, bz2_decompressor_type);
- Py_DECREF(bz2_decompressor_type);
- if (rc < 0) {
+ if (PyModule_AddType(module, state->bz2_decompressor_type) < 0) {
return -1;
}
return 0;
}
+static int
+_bz2_traverse(PyObject *module, visitproc visit, void *arg)
+{
+ _bz2_state *state = get_module_state(module);
+ Py_VISIT(state->bz2_compressor_type);
+ Py_VISIT(state->bz2_decompressor_type);
+ return 0;
+}
+
+static int
+_bz2_clear(PyObject *module)
+{
+ _bz2_state *state = get_module_state(module);
+ Py_CLEAR(state->bz2_compressor_type);
+ Py_CLEAR(state->bz2_decompressor_type);
+ return 0;
+}
+
+static void
+_bz2_free(void *module)
+{
+ (void)_bz2_clear((PyObject *)module);
+}
+
static struct PyModuleDef_Slot _bz2_slots[] = {
{Py_mod_exec, _bz2_exec},
{0, NULL}
@@ -795,6 +805,10 @@ static struct PyModuleDef_Slot _bz2_slots[] = {
static struct PyModuleDef _bz2module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "_bz2",
+ .m_size = sizeof(_bz2_state),
+ .m_traverse = _bz2_traverse,
+ .m_clear = _bz2_clear,
+ .m_free = _bz2_free,
.m_slots = _bz2_slots,
};
diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c
index b572d8c..bccab86 100644
--- a/Modules/_lzmamodule.c
+++ b/Modules/_lzmamodule.c
@@ -734,7 +734,8 @@ Compressor_init_raw(_lzma_state *state, lzma_stream *lzs, PyObject *filterspecs)
}
/*[-clinic input]
-_lzma.LZMACompressor.__init__
+@classmethod
+_lzma.LZMACompressor.__new__
format: int(c_default="FORMAT_XZ") = FORMAT_XZ
The container format to use for the output. This can
@@ -765,8 +766,8 @@ the raw compressor does not support preset compression levels.
For one-shot compression, use the compress() function instead.
[-clinic start generated code]*/
-static int
-Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
+static PyObject *
+Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
static char *arg_names[] = {"format", "check", "preset", "filters", NULL};
int format = FORMAT_XZ;
@@ -774,31 +775,37 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
uint32_t preset = LZMA_PRESET_DEFAULT;
PyObject *preset_obj = Py_None;
PyObject *filterspecs = Py_None;
- _lzma_state *state = PyType_GetModuleState(Py_TYPE(self));
+ Compressor *self;
+
+ _lzma_state *state = PyType_GetModuleState(type);
assert(state != NULL);
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|iiOO:LZMACompressor", arg_names,
&format, &check, &preset_obj,
&filterspecs)) {
- return -1;
+ return NULL;
}
if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) {
PyErr_SetString(PyExc_ValueError,
"Integrity checks are only supported by FORMAT_XZ");
- return -1;
+ return NULL;
}
if (preset_obj != Py_None && filterspecs != Py_None) {
PyErr_SetString(PyExc_ValueError,
"Cannot specify both preset and filter chain");
- return -1;
+ return NULL;
}
- if (preset_obj != Py_None) {
- if (!uint32_converter(preset_obj, &preset)) {
- return -1;
- }
+ if (preset_obj != Py_None && !uint32_converter(preset_obj, &preset)) {
+ return NULL;
+ }
+
+ assert(type != NULL && type->tp_alloc != NULL);
+ self = (Compressor *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
}
self->alloc.opaque = NULL;
@@ -808,8 +815,9 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
self->lock = PyThread_allocate_lock();
if (self->lock == NULL) {
+ Py_DECREF(self);
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
- return -1;
+ return NULL;
}
self->flushed = 0;
@@ -819,31 +827,33 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs)
check = LZMA_CHECK_CRC64;
}
if (Compressor_init_xz(state, &self->lzs, check, preset, filterspecs) != 0) {
- break;
+ goto error;
}
- return 0;
+ break;
case FORMAT_ALONE:
if (Compressor_init_alone(state, &self->lzs, preset, filterspecs) != 0) {
- break;
+ goto error;
}
- return 0;
+ break;
case FORMAT_RAW:
if (Compressor_init_raw(state, &self->lzs, filterspecs) != 0) {
- break;
+ goto error;
}
- return 0;
+ break;
default:
PyErr_Format(PyExc_ValueError,
"Invalid container format: %d", format);
- break;
+ goto error;
}
- PyThread_free_lock(self->lock);
- self->lock = NULL;
- return -1;
+ return (PyObject *)self;
+
+error:
+ Py_DECREF(self);
+ return NULL;
}
static void
@@ -902,8 +912,7 @@ PyDoc_STRVAR(Compressor_doc,
static PyType_Slot lzma_compressor_type_slots[] = {
{Py_tp_dealloc, Compressor_dealloc},
{Py_tp_methods, Compressor_methods},
- {Py_tp_init, Compressor_init},
- {Py_tp_new, PyType_GenericNew},
+ {Py_tp_new, Compressor_new},
{Py_tp_doc, (char *)Compressor_doc},
{Py_tp_traverse, Compressor_traverse},
{0, 0}
@@ -1165,7 +1174,8 @@ Decompressor_init_raw(_lzma_state *state, lzma_stream *lzs, PyObject *filterspec
}
/*[clinic input]
-_lzma.LZMADecompressor.__init__
+@classmethod
+_lzma.LZMADecompressor.__new__
format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO
Specifies the container format of the input stream. If this is
@@ -1189,54 +1199,57 @@ Create a decompressor object for decompressing data incrementally.
For one-shot decompression, use the decompress() function instead.
[clinic start generated code]*/
-static int
-_lzma_LZMADecompressor___init___impl(Decompressor *self, int format,
- PyObject *memlimit, PyObject *filters)
-/*[clinic end generated code: output=3e1821f8aa36564c input=81fe684a6c2f8a27]*/
+static PyObject *
+_lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
+ PyObject *memlimit, PyObject *filters)
+/*[clinic end generated code: output=2d46d5e70f10bc7f input=ca40cd1cb1202b0d]*/
{
+ Decompressor *self;
const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK;
uint64_t memlimit_ = UINT64_MAX;
lzma_ret lzret;
- _lzma_state *state = PyType_GetModuleState(Py_TYPE(self));
+ _lzma_state *state = PyType_GetModuleState(type);
assert(state != NULL);
if (memlimit != Py_None) {
if (format == FORMAT_RAW) {
PyErr_SetString(PyExc_ValueError,
"Cannot specify memory limit with FORMAT_RAW");
- return -1;
+ return NULL;
}
memlimit_ = PyLong_AsUnsignedLongLong(memlimit);
if (PyErr_Occurred()) {
- return -1;
+ return NULL;
}
}
if (format == FORMAT_RAW && filters == Py_None) {
PyErr_SetString(PyExc_ValueError,
"Must specify filters for FORMAT_RAW");
- return -1;
+ return NULL;
} else if (format != FORMAT_RAW && filters != Py_None) {
PyErr_SetString(PyExc_ValueError,
"Cannot specify filters except with FORMAT_RAW");
- return -1;
+ return NULL;
}
+ assert(type != NULL && type->tp_alloc != NULL);
+ self = (Decompressor *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
+ }
self->alloc.opaque = NULL;
self->alloc.alloc = PyLzma_Malloc;
self->alloc.free = PyLzma_Free;
self->lzs.allocator = &self->alloc;
self->lzs.next_in = NULL;
- PyThread_type_lock lock = PyThread_allocate_lock();
- if (lock == NULL) {
+ self->lock = PyThread_allocate_lock();
+ if (self->lock == NULL) {
+ Py_DECREF(self);
PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
- return -1;
- }
- if (self->lock != NULL) {
- PyThread_free_lock(self->lock);
+ return NULL;
}
- self->lock = lock;
self->check = LZMA_CHECK_UNKNOWN;
self->needs_input = 1;
@@ -1251,43 +1264,43 @@ _lzma_LZMADecompressor___init___impl(Decompressor *self, int format,
case FORMAT_AUTO:
lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags);
if (catch_lzma_error(state, lzret)) {
- break;
+ goto error;
}
- return 0;
+ break;
case FORMAT_XZ:
lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags);
if (catch_lzma_error(state, lzret)) {
- break;
+ goto error;
}
- return 0;
+ break;
case FORMAT_ALONE:
self->check = LZMA_CHECK_NONE;
lzret = lzma_alone_decoder(&self->lzs, memlimit_);
if (catch_lzma_error(state, lzret)) {
- break;
+ goto error;
}
- return 0;
+ break;
case FORMAT_RAW:
self->check = LZMA_CHECK_NONE;
if (Decompressor_init_raw(state, &self->lzs, filters) == -1) {
- break;
+ goto error;
}
- return 0;
+ break;
default:
PyErr_Format(PyExc_ValueError,
"Invalid container format: %d", format);
- break;
+ goto error;
}
+ return (PyObject *)self;
+
error:
- Py_CLEAR(self->unused_data);
- PyThread_free_lock(self->lock);
- self->lock = NULL;
- return -1;
+ Py_DECREF(self);
+ return NULL;
}
static void
@@ -1345,9 +1358,8 @@ static PyMemberDef Decompressor_members[] = {
static PyType_Slot lzma_decompressor_type_slots[] = {
{Py_tp_dealloc, Decompressor_dealloc},
{Py_tp_methods, Decompressor_methods},
- {Py_tp_init, _lzma_LZMADecompressor___init__},
- {Py_tp_new, PyType_GenericNew},
- {Py_tp_doc, (char *)_lzma_LZMADecompressor___init____doc__},
+ {Py_tp_new, _lzma_LZMADecompressor},
+ {Py_tp_doc, (char *)_lzma_LZMADecompressor__doc__},
{Py_tp_traverse, Decompressor_traverse},
{Py_tp_members, Decompressor_members},
{0, 0}
diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h
index 50a48b0..d7797d6 100644
--- a/Modules/clinic/_bz2module.c.h
+++ b/Modules/clinic/_bz2module.c.h
@@ -71,6 +71,48 @@ _bz2_BZ2Compressor_flush(BZ2Compressor *self, PyObject *Py_UNUSED(ignored))
return _bz2_BZ2Compressor_flush_impl(self);
}
+PyDoc_STRVAR(_bz2_BZ2Compressor__doc__,
+"BZ2Compressor(compresslevel=9, /)\n"
+"--\n"
+"\n"
+"Create a compressor object for compressing data incrementally.\n"
+"\n"
+" compresslevel\n"
+" Compression level, as a number between 1 and 9.\n"
+"\n"
+"For one-shot compression, use the compress() function instead.");
+
+static PyObject *
+_bz2_BZ2Compressor_impl(PyTypeObject *type, int compresslevel);
+
+static PyObject *
+_bz2_BZ2Compressor(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ PyObject *return_value = NULL;
+ PyTypeObject *base_tp = clinic_state()->bz2_compressor_type;
+ int compresslevel = 9;
+
+ if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
+ !_PyArg_NoKeywords("BZ2Compressor", kwargs)) {
+ goto exit;
+ }
+ if (!_PyArg_CheckPositional("BZ2Compressor", PyTuple_GET_SIZE(args), 0, 1)) {
+ goto exit;
+ }
+ if (PyTuple_GET_SIZE(args) < 1) {
+ goto skip_optional;
+ }
+ compresslevel = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0));
+ if (compresslevel == -1 && PyErr_Occurred()) {
+ goto exit;
+ }
+skip_optional:
+ return_value = _bz2_BZ2Compressor_impl(type, compresslevel);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__,
"decompress($self, /, data, max_length=-1)\n"
"--\n"
@@ -168,4 +210,35 @@ exit:
return return_value;
}
-/*[clinic end generated code: output=829bed4097cf2e63 input=a9049054013a1b77]*/
+
+PyDoc_STRVAR(_bz2_BZ2Decompressor__doc__,
+"BZ2Decompressor()\n"
+"--\n"
+"\n"
+"Create a decompressor object for decompressing data incrementally.\n"
+"\n"
+"For one-shot decompression, use the decompress() function instead.");
+
+static PyObject *
+_bz2_BZ2Decompressor_impl(PyTypeObject *type);
+
+static PyObject *
+_bz2_BZ2Decompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ PyObject *return_value = NULL;
+ PyTypeObject *base_tp = clinic_state()->bz2_decompressor_type;
+
+ if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
+ !_PyArg_NoPositional("BZ2Decompressor", args)) {
+ goto exit;
+ }
+ if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
+ !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) {
+ goto exit;
+ }
+ return_value = _bz2_BZ2Decompressor_impl(type);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: output=805400e4805098ec input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h
index 286d2b0..9b396a5 100644
--- a/Modules/clinic/_lzmamodule.c.h
+++ b/Modules/clinic/_lzmamodule.c.h
@@ -169,7 +169,7 @@ exit:
return return_value;
}
-PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__,
+PyDoc_STRVAR(_lzma_LZMADecompressor__doc__,
"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n"
"--\n"
"\n"
@@ -192,14 +192,14 @@ PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__,
"\n"
"For one-shot decompression, use the decompress() function instead.");
-static int
-_lzma_LZMADecompressor___init___impl(Decompressor *self, int format,
- PyObject *memlimit, PyObject *filters);
+static PyObject *
+_lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
+ PyObject *memlimit, PyObject *filters);
-static int
-_lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+static PyObject *
+_lzma_LZMADecompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
- int return_value = -1;
+ PyObject *return_value = NULL;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
#define NUM_KEYWORDS 3
@@ -257,7 +257,7 @@ _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs
}
filters = fastargs[2];
skip_optional_pos:
- return_value = _lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters);
+ return_value = _lzma_LZMADecompressor_impl(type, format, memlimit, filters);
exit:
return return_value;
@@ -338,4 +338,4 @@ exit:
return return_value;
}
-/*[clinic end generated code: output=da3e83ba97244044 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=96c1fbdada1ef232 input=a9049054013a1b77]*/