Skip to content

Commit 828682d

Browse files
authored
[3.13] gh-116946: fully implement GC protocol for lzma objects (GH-138288) (#138323)
(cherry picked from commit 3ea16f9)
1 parent 90036f5 commit 828682d

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

Modules/_lzmamodule.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ typedef struct {
126126
PyThread_type_lock lock;
127127
} Decompressor;
128128

129+
#define Compressor_CAST(op) ((Compressor *)(op))
130+
#define Decompressor_CAST(op) ((Decompressor *)(op))
131+
129132
/* Helper functions. */
130133

131134
static int
@@ -857,14 +860,16 @@ Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
857860
}
858861

859862
static void
860-
Compressor_dealloc(Compressor *self)
863+
Compressor_dealloc(PyObject *op)
861864
{
865+
PyTypeObject *tp = Py_TYPE(op);
866+
PyObject_GC_UnTrack(op);
867+
Compressor *self = Compressor_CAST(op);
862868
lzma_end(&self->lzs);
863869
if (self->lock != NULL) {
864870
PyThread_free_lock(self->lock);
865871
}
866-
PyTypeObject *tp = Py_TYPE(self);
867-
tp->tp_free((PyObject *)self);
872+
tp->tp_free(self);
868873
Py_DECREF(tp);
869874
}
870875

@@ -875,7 +880,7 @@ static PyMethodDef Compressor_methods[] = {
875880
};
876881

877882
static int
878-
Compressor_traverse(Compressor *self, visitproc visit, void *arg)
883+
Compressor_traverse(PyObject *self, visitproc visit, void *arg)
879884
{
880885
Py_VISIT(Py_TYPE(self));
881886
return 0;
@@ -925,7 +930,7 @@ static PyType_Spec lzma_compressor_type_spec = {
925930
// lzma_compressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
926931
// which prevents to create a subclass.
927932
// So calling PyType_GetModuleState() in this file is always safe.
928-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
933+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
929934
.slots = lzma_compressor_type_slots,
930935
};
931936

@@ -1304,8 +1309,11 @@ _lzma_LZMADecompressor_impl(PyTypeObject *type, int format,
13041309
}
13051310

13061311
static void
1307-
Decompressor_dealloc(Decompressor *self)
1312+
Decompressor_dealloc(PyObject *op)
13081313
{
1314+
PyTypeObject *tp = Py_TYPE(op);
1315+
PyObject_GC_UnTrack(op);
1316+
Decompressor *self = Decompressor_CAST(op);
13091317
if(self->input_buffer != NULL)
13101318
PyMem_Free(self->input_buffer);
13111319

@@ -1314,13 +1322,12 @@ Decompressor_dealloc(Decompressor *self)
13141322
if (self->lock != NULL) {
13151323
PyThread_free_lock(self->lock);
13161324
}
1317-
PyTypeObject *tp = Py_TYPE(self);
1318-
tp->tp_free((PyObject *)self);
1325+
tp->tp_free(self);
13191326
Py_DECREF(tp);
13201327
}
13211328

13221329
static int
1323-
Decompressor_traverse(Decompressor *self, visitproc visit, void *arg)
1330+
Decompressor_traverse(PyObject *self, visitproc visit, void *arg)
13241331
{
13251332
Py_VISIT(Py_TYPE(self));
13261333
return 0;
@@ -1372,7 +1379,7 @@ static PyType_Spec lzma_decompressor_type_spec = {
13721379
// lzma_decompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
13731380
// which prevents to create a subclass.
13741381
// So calling PyType_GetModuleState() in this file is always safe.
1375-
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE),
1382+
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC),
13761383
.slots = lzma_decompressor_type_slots,
13771384
};
13781385

0 commit comments

Comments
 (0)