Tim Peters <t...@python.org> added the comment:

Ah, I missed that `cache` is global.  So it will hold reachable strong refs to 
the weakrefs stored for the dict's values.  So gc will run the callbacks 
associated with weakrefs' trash referents.

I think you're out of luck.  Nothing is defined about the order in which the 
stuff in cyclic trash is destroyed.  gc has no knowledge of your intended 
semantics, and no way to be taught.  You happened to create code that assumed 
(albeit indirectly & subtly) a finalizer would run before a relevant callback, 
but someone else could create code assuming the reverse.

It so happens that gc forces all callbacks to run before it forces any 
finalizers to run, and I'm loathe to change that code - weakref callbacks in 
particular have been an historical segfault factory, so nobody will touch that 
code without extraordinarily strong reason to risk it.  But I'll add Pablo here 
just in case he's feeling adventurous ;-)

In any case, I'd say it's always _best_ practice to never delete a key from any 
kind of weak dict except under protection of a try/except block.  The point of 
a weak dict is that entries can vanish "by magic".  And in this particular 
case, by deeper magic than was anticipated ;-)

----------
nosy: +pablogsal

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue40312>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to