Message394568
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. |
|
Date |
User |
Action |
Args |
2021-05-27 16:58:40 | vstinner | set | recipients:
+ vstinner, nascheme, ncoghlan, christian.heimes, corona10, pablogsal, miss-islington, shihai1991, erlendaasland, kj |
2021-05-27 16:58:40 | vstinner | set | messageid: <1622134720.01.0.281204043319.issue42972@roundup.psfhosted.org> |
2021-05-27 16:58:40 | vstinner | link | issue42972 messages |
2021-05-27 16:58:39 | vstinner | create | |
|