[Python-Dev] The Amazing Unreferenced Weakref

Larry Hastings larry at hastings.org
Tue Sep 6 18:49:36 EDT 2016


This is all about current (3.6) trunk.

In Objects/weakrefobject.c, we have the function 
PyObject_ClearWeakRefs().  This is called when a generic object that 
supports weakrefs is destroyed; this is the code that calls the 
callbacks.  Here's a little paragraph of code from the center:

    for (i = 0; i < count; ++i) {
         PyWeakReference *next = current->wr_next;

         if (((PyObject *)current)->ob_refcnt > 0)
         {
             Py_INCREF(current);
             PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
             PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
         }
         else {
             Py_DECREF(current->wr_callback);
         }
         current->wr_callback = NULL;
         clear_weakref(current);
         current = next;
    }

"current" is the doubly-linked list of PyWeakReference objects stored 
inside the object that's getting destroyed.

My question: under what circumstances would ob_refcnt ever be 0? The 
tp_dealloc handler for PyWeakReference * objects removes it from this 
list and frees the memory.  How could the reference count reach 0 
without tp_dealloc being called and it being removed from the list?

Scratching my head like crazy,


//arry/

p.s. If you're thinking "why does he care?", understanding this would 
maybe help with the Gilectomy.  So yes there's a point to this question.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20160906/477518a9/attachment.html>


More information about the Python-Dev mailing list