Skip to content

Commit f4151b8

Browse files
committed
fully implement GC protocol for _functools._lru_list_elem
1 parent 2a54acf commit f4151b8

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

Modules/_functoolsmodule.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,24 +1164,40 @@ typedef struct lru_list_elem {
11641164
static void
11651165
lru_list_elem_dealloc(PyObject *op)
11661166
{
1167+
PyTypeObject *tp = Py_TYPE(op);
1168+
PyObject_GC_UnTrack(op);
11671169
lru_list_elem *link = lru_list_elem_CAST(op);
1168-
PyTypeObject *tp = Py_TYPE(link);
11691170
Py_XDECREF(link->key);
11701171
Py_XDECREF(link->result);
11711172
tp->tp_free(link);
11721173
Py_DECREF(tp);
11731174
}
11741175

1176+
static int
1177+
lru_list_elem_traverse(PyObject *op, visitproc visit, void *arg)
1178+
{
1179+
lru_list_elem *link = lru_list_elem_CAST(op);
1180+
Py_VISIT(Py_TYPE(op));
1181+
Py_VISIT(link->key);
1182+
Py_VISIT(link->result);
1183+
return 0;
1184+
}
1185+
11751186
static PyType_Slot lru_list_elem_type_slots[] = {
11761187
{Py_tp_dealloc, lru_list_elem_dealloc},
1188+
{Py_tp_traverse, lru_list_elem_traverse},
11771189
{0, 0}
11781190
};
11791191

11801192
static PyType_Spec lru_list_elem_type_spec = {
11811193
.name = "functools._lru_list_elem",
11821194
.basicsize = sizeof(lru_list_elem),
1183-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
1184-
Py_TPFLAGS_IMMUTABLETYPE,
1195+
.flags = (
1196+
Py_TPFLAGS_DEFAULT
1197+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
1198+
| Py_TPFLAGS_IMMUTABLETYPE
1199+
| Py_TPFLAGS_HAVE_GC
1200+
),
11851201
.slots = lru_list_elem_type_slots
11861202
};
11871203

@@ -1454,8 +1470,10 @@ bounded_lru_cache_update_lock_held(lru_cache_object *self,
14541470
self->root.next == &self->root)
14551471
{
14561472
/* Cache is not full, so put the result in a new link */
1457-
link = (lru_list_elem *)PyObject_New(lru_list_elem,
1458-
self->lru_list_elem_type);
1473+
PyTypeObject *type = self->lru_list_elem_type;
1474+
assert(type != NULL);
1475+
assert(type->tp_alloc != NULL);
1476+
link = (lru_list_elem *)type->tp_alloc(type, 0);
14591477
if (link == NULL) {
14601478
Py_DECREF(key);
14611479
Py_DECREF(result);

0 commit comments

Comments
 (0)