bpo-44116: Add GC support to _csv heap types (GH-26074) (GH-26081)

(cherry picked from commit e5ba1fe995)
This commit is contained in:
Miss Islington (bot) 2021-05-12 11:56:19 -07:00 committed by GitHub
parent 1ee58f2524
commit ba260acb22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -316,17 +316,12 @@ static void
Dialect_dealloc(DialectObj *self) Dialect_dealloc(DialectObj *self)
{ {
PyTypeObject *tp = Py_TYPE(self); PyTypeObject *tp = Py_TYPE(self);
Py_CLEAR(self->lineterminator); PyObject_GC_UnTrack(self);
tp->tp_free((PyObject *)self); tp->tp_clear((PyObject *)self);
PyObject_GC_Del(self);
Py_DECREF(tp); Py_DECREF(tp);
} }
static void
Dialect_finalize(DialectObj *self)
{
Py_CLEAR(self->lineterminator);
}
static char *dialect_kws[] = { static char *dialect_kws[] = {
"dialect", "dialect",
"delimiter", "delimiter",
@ -512,21 +507,37 @@ PyDoc_STRVAR(Dialect_Type_doc,
"\n" "\n"
"The Dialect type records CSV parsing and generation options.\n"); "The Dialect type records CSV parsing and generation options.\n");
static int
Dialect_clear(DialectObj *self)
{
Py_CLEAR(self->lineterminator);
return 0;
}
static int
Dialect_traverse(DialectObj *self, visitproc visit, void *arg)
{
Py_VISIT(self->lineterminator);
Py_VISIT(Py_TYPE(self));
return 0;
}
static PyType_Slot Dialect_Type_slots[] = { static PyType_Slot Dialect_Type_slots[] = {
{Py_tp_doc, (char*)Dialect_Type_doc}, {Py_tp_doc, (char*)Dialect_Type_doc},
{Py_tp_members, Dialect_memberlist}, {Py_tp_members, Dialect_memberlist},
{Py_tp_getset, Dialect_getsetlist}, {Py_tp_getset, Dialect_getsetlist},
{Py_tp_new, dialect_new}, {Py_tp_new, dialect_new},
{Py_tp_methods, dialect_methods}, {Py_tp_methods, dialect_methods},
{Py_tp_finalize, Dialect_finalize},
{Py_tp_dealloc, Dialect_dealloc}, {Py_tp_dealloc, Dialect_dealloc},
{Py_tp_clear, Dialect_clear},
{Py_tp_traverse, Dialect_traverse},
{0, NULL} {0, NULL}
}; };
PyType_Spec Dialect_Type_spec = { PyType_Spec Dialect_Type_spec = {
.name = "_csv.Dialect", .name = "_csv.Dialect",
.basicsize = sizeof(DialectObj), .basicsize = sizeof(DialectObj),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
.slots = Dialect_Type_slots, .slots = Dialect_Type_slots,
}; };
@ -885,9 +896,7 @@ Reader_dealloc(ReaderObj *self)
{ {
PyTypeObject *tp = Py_TYPE(self); PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(self); PyObject_GC_UnTrack(self);
Py_CLEAR(self->dialect); tp->tp_clear((PyObject *)self);
Py_CLEAR(self->input_iter);
Py_CLEAR(self->fields);
if (self->field != NULL) { if (self->field != NULL) {
PyMem_Free(self->field); PyMem_Free(self->field);
self->field = NULL; self->field = NULL;
@ -896,24 +905,13 @@ Reader_dealloc(ReaderObj *self)
Py_DECREF(tp); Py_DECREF(tp);
} }
static void
Reader_finalize(ReaderObj *self)
{
Py_CLEAR(self->dialect);
Py_CLEAR(self->input_iter);
Py_CLEAR(self->fields);
if (self->field != NULL) {
PyMem_Free(self->field);
self->field = NULL;
}
}
static int static int
Reader_traverse(ReaderObj *self, visitproc visit, void *arg) Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
{ {
Py_VISIT(self->dialect); Py_VISIT(self->dialect);
Py_VISIT(self->input_iter); Py_VISIT(self->input_iter);
Py_VISIT(self->fields); Py_VISIT(self->fields);
Py_VISIT(Py_TYPE(self));
return 0; return 0;
} }
@ -948,12 +946,11 @@ static struct PyMemberDef Reader_memberlist[] = {
static PyType_Slot Reader_Type_slots[] = { static PyType_Slot Reader_Type_slots[] = {
{Py_tp_doc, (char*)Reader_Type_doc}, {Py_tp_doc, (char*)Reader_Type_doc},
{Py_tp_traverse, Reader_traverse}, {Py_tp_traverse, Reader_traverse},
{Py_tp_clear, Reader_clear},
{Py_tp_iter, PyObject_SelfIter}, {Py_tp_iter, PyObject_SelfIter},
{Py_tp_iternext, Reader_iternext}, {Py_tp_iternext, Reader_iternext},
{Py_tp_methods, Reader_methods}, {Py_tp_methods, Reader_methods},
{Py_tp_members, Reader_memberlist}, {Py_tp_members, Reader_memberlist},
{Py_tp_finalize, Reader_finalize}, {Py_tp_clear, Reader_clear},
{Py_tp_dealloc, Reader_dealloc}, {Py_tp_dealloc, Reader_dealloc},
{0, NULL} {0, NULL}
}; };
@ -1339,6 +1336,7 @@ Writer_traverse(WriterObj *self, visitproc visit, void *arg)
Py_VISIT(self->dialect); Py_VISIT(self->dialect);
Py_VISIT(self->write); Py_VISIT(self->write);
Py_VISIT(self->error_obj); Py_VISIT(self->error_obj);
Py_VISIT(Py_TYPE(self));
return 0; return 0;
} }
@ -1352,12 +1350,16 @@ Writer_clear(WriterObj *self)
} }
static void static void
Writer_finalize(WriterObj *self) Writer_dealloc(WriterObj *self)
{ {
Writer_clear(self); PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(self);
tp->tp_clear((PyObject *)self);
if (self->rec != NULL) { if (self->rec != NULL) {
PyMem_Free(self->rec); PyMem_Free(self->rec);
} }
PyObject_GC_Del(self);
Py_DECREF(tp);
} }
PyDoc_STRVAR(Writer_Type_doc, PyDoc_STRVAR(Writer_Type_doc,
@ -1368,10 +1370,10 @@ PyDoc_STRVAR(Writer_Type_doc,
); );
static PyType_Slot Writer_Type_slots[] = { static PyType_Slot Writer_Type_slots[] = {
{Py_tp_finalize, Writer_finalize},
{Py_tp_doc, (char*)Writer_Type_doc}, {Py_tp_doc, (char*)Writer_Type_doc},
{Py_tp_traverse, Writer_traverse}, {Py_tp_traverse, Writer_traverse},
{Py_tp_clear, Writer_clear}, {Py_tp_clear, Writer_clear},
{Py_tp_dealloc, Writer_dealloc},
{Py_tp_methods, Writer_methods}, {Py_tp_methods, Writer_methods},
{Py_tp_members, Writer_memberlist}, {Py_tp_members, Writer_memberlist},
{0, NULL} {0, NULL}