This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author konrad.schwarz
Recipients konrad.schwarz, mark.dickinson, pitrou
Date 2021-03-03.18:31:00
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <017001d7105b$5b37a240$11a6e6c0$@gmail.com>
In-reply-to <1614789566.91.0.756372884445.issue43383@roundup.psfhosted.org>
Content
> If I understand correctly, the reported bug is that you're seeing a weakref callback being executed
> after the weakref.ref instance it's attached to is deleted. Is that correct?

Exactly.  I del what should be the only reference to the weakref.ref/proxy, then del the weakref.ref's referent.
The weakref.ref's callback is executed.

> Do you have a minimal example we can use to reproduce the effect? Without such an example, there's not
> much of a realistic path to moving this forward.

Unfortunately, not at the moment.

> However, my suspicion is that that's not what's actually happening here. I suspect that when you say
> "after the corresponding weak reference has been deleted with del", that the "del" statement you refer
> to is not actually deleting the last reference to the weakref.ref object, so the weakref still exists
> after the "del". One easy way that this could happen is if the weakref is part of a reference cycle
> (and I know from personal experience that it's horribly easy to accidentally *create* reference cycles
> via weakref callbacks, especially if those callbacks refer to instance methods).

I tried to be as punctilious as I could to prevent this sort of thing from happening.
The weird thing is that the error does not occur when I single step the code in PDB.
It must be something internal to CPython, some sort of optimization.
Are local variables/stack frames cleaned lazily?  Is the last accessed value of a
dictionary cached internally, increasing its reference count?

I've worked around the problem by double checking in the callback method that it actually should execute;
i.e. in my case, that the object has not been removed (del) from a dictionary (which should be the
single reference to the object).

If the problem does indeed lie with CPython, but has too much of a performance/maintenance impact,
perhaps a caveat could be added to the documentation to the effect of "The lifetime of an object
may be longer than what a programmer expects causing a weakref's callback to be invoked at
a surprising time; it is good practice to program the callback defensively."
History
Date User Action Args
2021-03-03 18:31:01konrad.schwarzsetrecipients: + konrad.schwarz, mark.dickinson, pitrou
2021-03-03 18:31:01konrad.schwarzlinkissue43383 messages
2021-03-03 18:31:00konrad.schwarzcreate