Tim Peters added the comment:

I think Antoine is right on all counts.  The most surprising bit may be that p, 
c, and c2 are in reference cycles, but - surprising or not - that's always been 
true.  The reason "it worked" before 3.4 is that CPython happened to break the 
cycles via the nasty hack of binding each module global to None at shutdown.

minrk, note that gc in CPython does not (for example) run in a separate thread. 
 That's why, when it triggers, the infinite loop in your Parent.__del__ will in 
fact run forever.  gc runs in the same thread (the main thread) as 
Parent.__del__, so spinning in the Parent.__del__ loop prevents anything else 
(including more gc) from ever being done.

Take out the infinite loop, and all three objects (p, c, c2) are collected.  
But the order in which they're collected isn't defined (because they're all in 
cyclic trash), and even changes from run to run because hash randomization 
changes the order in which they appear when traversing testgc.__dict__.

An interesting question remaining is how you _could_ force a finalization order 
in this case, in a way that doesn't rely on implementation accidents.  A clean 
way doesn't spring to my mind immediately.

----------

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

Reply via email to