(inspired by #95302 (comment))
In Objects/weakrefobject.c, the clear_weakref() function is used to:
- pop the
PyWeakReference object off its referenced object's tp_weaklist (a linked list)
- clear (but not call) the callback, if any
However, in the places it is used, it isn't clear what it's doing. When adding a new use of clear_weakref() in one of my PRs it was particularly confusing to a reviewer what the relationship was between clear_weakref() and an object's weakref list (i.e. tp_weaklist).
While we could simply rename it to "remove_and_clear_weakref", it may make sense to do the following:
- move the linked-list part to a separate
remove_weakref() that has an explicit PyWeakReference ** parameter
- (hence, remove the linked list parts from
clear_weakref())
- add
remove_weakref_from_referent() which calls GET_WEAKREFS_LISTPTR(self->wr_object) and calls remove_weakref() on it
- add a call to it everywhere we already call
clear_weakref()
Other observations:
- currently we aren't reseting
self->hash or self->vectorcall to NULL in clear_weakref()
- we may be leaking weakref objects
PyObject_ClearWeakRefs() when the weakref doesn't have a callback
(inspired by #95302 (comment))
In Objects/weakrefobject.c, the
clear_weakref()function is used to:PyWeakReferenceobject off its referenced object'stp_weaklist(a linked list)However, in the places it is used, it isn't clear what it's doing. When adding a new use of
clear_weakref()in one of my PRs it was particularly confusing to a reviewer what the relationship was betweenclear_weakref()and an object's weakref list (i.e.tp_weaklist).While we could simply rename it to "remove_and_clear_weakref", it may make sense to do the following:
remove_weakref()that has an explicitPyWeakReference **parameterclear_weakref())remove_weakref_from_referent()which callsGET_WEAKREFS_LISTPTR(self->wr_object)and callsremove_weakref()on itclear_weakref()Other observations:
self->hashorself->vectorcallto NULL inclear_weakref()PyObject_ClearWeakRefs()when the weakref doesn't have a callback