Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c8cc39d

Browse files
authored
[3.14] gh-116946: fully implement GC protocol for zlib objects (GH-138290) (#138327)
1 parent 664d17f commit c8cc39d

File tree

1 file changed

+58
-19
lines changed

1 file changed

+58
-19
lines changed

Modules/zlibmodule.c

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ static compobject *
263263
newcompobject(PyTypeObject *type)
264264
{
265265
compobject *self;
266-
self = PyObject_New(compobject, type);
266+
assert(type != NULL);
267+
assert(type->tp_alloc != NULL);
268+
self = _compobject_CAST(type->tp_alloc(type, 0));
267269
if (self == NULL)
268270
return NULL;
269271
self->eof = 0;
@@ -706,33 +708,41 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict)
706708
}
707709

708710
static void
709-
Dealloc(compobject *self)
711+
compobject_dealloc_impl(PyObject *op, int (*dealloc)(z_streamp))
710712
{
711-
PyTypeObject *type = Py_TYPE(self);
713+
PyTypeObject *type = Py_TYPE(op);
714+
PyObject_GC_UnTrack(op);
715+
compobject *self = _compobject_CAST(op);
716+
if (self->is_initialised) {
717+
(void)dealloc(&self->zst);
718+
}
712719
PyThread_free_lock(self->lock);
713720
Py_XDECREF(self->unused_data);
714721
Py_XDECREF(self->unconsumed_tail);
715722
Py_XDECREF(self->zdict);
716-
PyObject_Free(self);
723+
type->tp_free(self);
717724
Py_DECREF(type);
718725
}
719726

727+
static int
728+
compobject_traverse(PyObject *op, visitproc visit, void *arg)
729+
{
730+
compobject *self = _compobject_CAST(op);
731+
Py_VISIT(Py_TYPE(op));
732+
Py_VISIT(self->zdict);
733+
return 0;
734+
}
735+
720736
static void
721737
Comp_dealloc(PyObject *op)
722738
{
723-
compobject *self = _compobject_CAST(op);
724-
if (self->is_initialised)
725-
(void)deflateEnd(&self->zst);
726-
Dealloc(self);
739+
compobject_dealloc_impl(op, &deflateEnd);
727740
}
728741

729742
static void
730743
Decomp_dealloc(PyObject *op)
731744
{
732-
compobject *self = _compobject_CAST(op);
733-
if (self->is_initialised)
734-
(void)inflateEnd(&self->zst);
735-
Dealloc(self);
745+
compobject_dealloc_impl(op, &inflateEnd);
736746
}
737747

738748
/*[clinic input]
@@ -1357,6 +1367,8 @@ typedef struct {
13571367
char needs_input;
13581368
} ZlibDecompressor;
13591369

1370+
#define ZlibDecompressor_CAST(op) ((ZlibDecompressor *)(op))
1371+
13601372
/*[clinic input]
13611373
class zlib.ZlibDecompressor "ZlibDecompressor *" "&ZlibDecompressorType"
13621374
[clinic start generated code]*/
@@ -1365,19 +1377,29 @@ class zlib.ZlibDecompressor "ZlibDecompressor *" "&ZlibDecompressorType"
13651377
static void
13661378
ZlibDecompressor_dealloc(PyObject *op)
13671379
{
1368-
ZlibDecompressor *self = (ZlibDecompressor*)op;
1369-
PyObject *type = (PyObject *)Py_TYPE(self);
1380+
PyTypeObject *type = Py_TYPE(op);
1381+
PyObject_GC_UnTrack(op);
1382+
ZlibDecompressor *self = ZlibDecompressor_CAST(op);
13701383
PyThread_free_lock(self->lock);
13711384
if (self->is_initialised) {
13721385
inflateEnd(&self->zst);
13731386
}
13741387
PyMem_Free(self->input_buffer);
13751388
Py_CLEAR(self->unused_data);
13761389
Py_CLEAR(self->zdict);
1377-
PyObject_Free(self);
1390+
type->tp_free(self);
13781391
Py_DECREF(type);
13791392
}
13801393

1394+
static int
1395+
ZlibDecompressor_traverse(PyObject *op, visitproc visit, void *arg)
1396+
{
1397+
ZlibDecompressor *self = ZlibDecompressor_CAST(op);
1398+
Py_VISIT(Py_TYPE(op));
1399+
Py_VISIT(self->zdict);
1400+
return 0;
1401+
}
1402+
13811403
static int
13821404
set_inflate_zdict_ZlibDecompressor(zlibstate *state, ZlibDecompressor *self)
13831405
{
@@ -1729,7 +1751,9 @@ ZlibDecompressor__new__(PyTypeObject *cls,
17291751
args, kwargs, format, keywords, &wbits, &zdict)) {
17301752
return NULL;
17311753
}
1732-
ZlibDecompressor *self = PyObject_New(ZlibDecompressor, cls);
1754+
1755+
assert(cls != NULL && cls->tp_alloc != NULL);
1756+
ZlibDecompressor *self = ZlibDecompressor_CAST(cls->tp_alloc(cls, 0));
17331757
if (self == NULL) {
17341758
return NULL;
17351759
}
@@ -1937,19 +1961,25 @@ static PyMethodDef zlib_methods[] =
19371961

19381962
static PyType_Slot Comptype_slots[] = {
19391963
{Py_tp_dealloc, Comp_dealloc},
1964+
{Py_tp_traverse, compobject_traverse},
19401965
{Py_tp_methods, comp_methods},
19411966
{0, 0},
19421967
};
19431968

19441969
static PyType_Spec Comptype_spec = {
19451970
.name = "zlib.Compress",
19461971
.basicsize = sizeof(compobject),
1947-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
1972+
.flags = (
1973+
Py_TPFLAGS_DEFAULT
1974+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
1975+
| Py_TPFLAGS_HAVE_GC
1976+
),
19481977
.slots= Comptype_slots,
19491978
};
19501979

19511980
static PyType_Slot Decomptype_slots[] = {
19521981
{Py_tp_dealloc, Decomp_dealloc},
1982+
{Py_tp_traverse, compobject_traverse},
19531983
{Py_tp_methods, Decomp_methods},
19541984
{Py_tp_members, Decomp_members},
19551985
{0, 0},
@@ -1958,12 +1988,17 @@ static PyType_Slot Decomptype_slots[] = {
19581988
static PyType_Spec Decomptype_spec = {
19591989
.name = "zlib.Decompress",
19601990
.basicsize = sizeof(compobject),
1961-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
1991+
.flags = (
1992+
Py_TPFLAGS_DEFAULT
1993+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
1994+
| Py_TPFLAGS_HAVE_GC
1995+
),
19621996
.slots = Decomptype_slots,
19631997
};
19641998

19651999
static PyType_Slot ZlibDecompressor_type_slots[] = {
19662000
{Py_tp_dealloc, ZlibDecompressor_dealloc},
2001+
{Py_tp_traverse, ZlibDecompressor_traverse},
19672002
{Py_tp_members, ZlibDecompressor_members},
19682003
{Py_tp_new, ZlibDecompressor__new__},
19692004
{Py_tp_doc, (char *)ZlibDecompressor__new____doc__},
@@ -1978,7 +2013,11 @@ static PyType_Spec ZlibDecompressor_type_spec = {
19782013
// ZlibDecompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
19792014
// which prevents to create a subclass.
19802015
// So calling PyType_GetModuleState() in this file is always safe.
1981-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
2016+
.flags = (
2017+
Py_TPFLAGS_DEFAULT
2018+
| Py_TPFLAGS_IMMUTABLETYPE
2019+
| Py_TPFLAGS_HAVE_GC
2020+
),
19822021
.slots = ZlibDecompressor_type_slots,
19832022
};
19842023
PyDoc_STRVAR(zlib_module_documentation,

0 commit comments

Comments
 (0)