[issue42972] [C API] Heap types (PyType_FromSpec) must fully implement the GC protocol
STINNER Victor
report at bugs.python.org
Thu May 27 12:58:40 EDT 2021
STINNER Victor <vstinner at python.org> added the comment:
I'm not sure that it's safe to call PyObject_ClearWeakRefs() in tp_clear function. PyObject_ClearWeakRefs() comment starts with:
"This function is called by the tp_dealloc handler to clear weak references."
For example in Modules/arraymodule.c, I don't understand well what assigns weakreflist and what is the object type. Is it a strong reference to a Python object? What is supposed to call Py_DECREF() on it?
Is it enought to call PyObject_ClearWeakRefs() in tp_dealloc?
subtype_dealloc() calls PyObject_ClearWeakRefs(self).
I wrote a short example:
---
import weakref
import ctypes
import sys
class A:
pass
obj=A()
assert obj.__weakref__ is None
wr1 = weakref.ref(obj)
assert obj.__weakref__ is wr1
print(type(wr1))
print("refcnt(wr1)", sys.getrefcount(wr1))
wr2 = weakref.ref(obj)
assert wr2 is wr1
assert obj.__weakref__ is wr1
print("refcnt(wr1)", sys.getrefcount(wr1))
_PyWeakref_GetWeakrefCount = ctypes.pythonapi._PyWeakref_GetWeakrefCount
_PyWeakref_GetWeakrefCount.argtypes = (ctypes.py_object,)
_PyWeakref_GetWeakrefCount.restype = ctypes.c_size_t
print("_PyWeakref_GetWeakrefCount:", _PyWeakref_GetWeakrefCount(wr1))
---
Output:
---
<class 'weakref'>
refcnt(wr1) 2
refcnt(wr1) 3
_PyWeakref_GetWeakrefCount: 1
---
In this case, wr2 is wr1, __weakreflist__ points to a weakref.ref object instance, and _PyWeakref_GetWeakrefCount() returns 1.
At the first weakref.ref() call, the reference count is 1: "wr1" variable holds this reference. I understand that obj stores a *weak* reference to the Python object "weakref.ref". So it doesn't have to DECREF anything.
----------
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue42972>
_______________________________________
More information about the Python-bugs-list
mailing list