Skip to content

Commit 90036f5

Browse files
authored
[3.13] pythongh-116946: fully implement GC protocol for bz2 objects (pythonGH-138266) (python#138322)
(cherry picked from commit 9be91f6)
1 parent aebf072 commit 90036f5

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

Modules/_bz2module.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ typedef struct {
129129
PyThread_type_lock lock;
130130
} BZ2Decompressor;
131131

132+
#define _BZ2Compressor_CAST(op) ((BZ2Compressor *)(op))
133+
#define _BZ2Decompressor_CAST(op) ((BZ2Decompressor *)(op))
134+
132135
/* Helper functions. */
133136

134137
static int
@@ -376,19 +379,21 @@ _bz2_BZ2Compressor_impl(PyTypeObject *type, int compresslevel)
376379
}
377380

378381
static void
379-
BZ2Compressor_dealloc(BZ2Compressor *self)
382+
BZ2Compressor_dealloc(PyObject *op)
380383
{
384+
PyTypeObject *tp = Py_TYPE(op);
385+
PyObject_GC_UnTrack(op);
386+
BZ2Compressor *self = _BZ2Compressor_CAST(op);
381387
BZ2_bzCompressEnd(&self->bzs);
382388
if (self->lock != NULL) {
383389
PyThread_free_lock(self->lock);
384390
}
385-
PyTypeObject *tp = Py_TYPE(self);
386-
tp->tp_free((PyObject *)self);
391+
tp->tp_free(self);
387392
Py_DECREF(tp);
388393
}
389394

390395
static int
391-
BZ2Compressor_traverse(BZ2Compressor *self, visitproc visit, void *arg)
396+
BZ2Compressor_traverse(PyObject *self, visitproc visit, void *arg)
392397
{
393398
Py_VISIT(Py_TYPE(self));
394399
return 0;
@@ -416,7 +421,7 @@ static PyType_Spec bz2_compressor_type_spec = {
416421
// bz2_compressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
417422
// which prevents to create a subclass.
418423
// So calling PyType_GetModuleState() in this file is always safe.
419-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
424+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
420425
.slots = bz2_compressor_type_slots,
421426
};
422427

@@ -680,8 +685,11 @@ _bz2_BZ2Decompressor_impl(PyTypeObject *type)
680685
}
681686

682687
static void
683-
BZ2Decompressor_dealloc(BZ2Decompressor *self)
688+
BZ2Decompressor_dealloc(PyObject *op)
684689
{
690+
PyTypeObject *tp = Py_TYPE(op);
691+
PyObject_GC_UnTrack(op);
692+
BZ2Decompressor *self = _BZ2Decompressor_CAST(op);
685693
if(self->input_buffer != NULL) {
686694
PyMem_Free(self->input_buffer);
687695
}
@@ -690,14 +698,12 @@ BZ2Decompressor_dealloc(BZ2Decompressor *self)
690698
if (self->lock != NULL) {
691699
PyThread_free_lock(self->lock);
692700
}
693-
694-
PyTypeObject *tp = Py_TYPE(self);
695-
tp->tp_free((PyObject *)self);
701+
tp->tp_free(self);
696702
Py_DECREF(tp);
697703
}
698704

699705
static int
700-
BZ2Decompressor_traverse(BZ2Decompressor *self, visitproc visit, void *arg)
706+
BZ2Decompressor_traverse(PyObject *self, visitproc visit, void *arg)
701707
{
702708
Py_VISIT(Py_TYPE(self));
703709
return 0;
@@ -744,7 +750,7 @@ static PyType_Spec bz2_decompressor_type_spec = {
744750
// bz2_decompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
745751
// which prevents to create a subclass.
746752
// So calling PyType_GetModuleState() in this file is always safe.
747-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
753+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
748754
.slots = bz2_decompressor_type_slots,
749755
};
750756

0 commit comments

Comments
 (0)