Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
bpo-40170: Fix PyType_Ready() refleak on static type
bpo-1635741, bpo-40170: When called on a static type with NULL
tp_base, PyType_Ready() no longer increments the reference count of
the PyBaseObject_Type ("object). PyTypeObject.tp_base is a strong
reference on a heap type, but it is borrowed reference on a static
type.

Fix 99 reference leaks at Python exit (showrefcount 18623 => 18524).
  • Loading branch information
vstinner committed Nov 11, 2020
commit c15a6c3d0d8f817e49d435e768524be14ac9ed30
1 change: 1 addition & 0 deletions Include/cpython/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ struct _typeobject {
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
// Strong reference on a heap type, borrowed reference on a static type
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
Expand Down
9 changes: 7 additions & 2 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -5487,8 +5487,13 @@ PyType_Ready(PyTypeObject *type)
/* Initialize tp_base (defaults to BaseObject unless that's us) */
base = type->tp_base;
if (base == NULL && type != &PyBaseObject_Type) {
base = type->tp_base = &PyBaseObject_Type;
Py_INCREF(base);
base = &PyBaseObject_Type;
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
type->tp_base = (PyTypeObject*)Py_NewRef((PyObject*)base);
}
else {
type->tp_base = base;
}
}

/* Now the only way base can still be NULL is if type is
Expand Down