[Python-Dev] Re: weakref callback vs gc vs threads

Tim Peters tim.peters at gmail.com
Fri Oct 29 21:59:37 CEST 2004

> The meaning of "clearing a weakref" has become ambiguous -- so far, to
> me (and I believe to Fred too) it's always meant both "set wr_object
> to Py_None" and "remove the weakref from its referent's list of
> weakrefs".  You're sometimes using it to mean only the former.  That
> may be a clever thing to do -- unsure yet.

It has one downside that seems rare (the full Zope3 test suite
provokes it, but not Python's):  say a weakref W "is cleared" just by
setting wr_object to Py_None.  If W's refcount later falls to 0,
weakref_dealloc() won't remove W from W's referent's list of weakrefs.
 That's the way clear_weakref() is written, and I think it has to be
that way:  if clear_weakref doesn't know what the referent is, it
can't find the pointer to the head of the referent's weakref list, so
it can't unlink W from the list correctly (unlike gc's doubly-linked
lists, weakref lists aren't circular, and don't have list heads)  This
leaves free'd memory *in* the referent's weakref list.  So if the
referent's refcount falls to 0 after that, then
PyObject_ClearWeakRefs() goes nuts trying to crawl over the freed
memory.  In a debug build that's obvious when it happens, because
_PyWeakref_GetWeakrefCount() hits a weakref object full of 0xdb bytes.

More information about the Python-Dev mailing list