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

Reply via email to