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.
   ">

(original) (raw)


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.