STINNER Victor <vstin...@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 <rep...@bugs.python.org> <https://bugs.python.org/issue42972> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com