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