>> The question is more why/how the code didn't crash before? :-)
>
> Typical case of a Schroedinbug.
I don't believe in the chaos :-)
I ran a "git bisect" since January 1st, 2017. Attached bug2.py started to crash since the following commit related to bpo-29049.
---
5a625d0aa6a6d9ec6574ee8344b41d63dcb9897e is the first bad commit
commit 5a625d0aa6a6d9ec6574ee8344b41d63dcb9897e
Author: INADA Naoki <songofacandy@gmail.com>
Date: Sat Dec 24 20:19:08 2016 +0900
Issue #29049: Call _PyObject_GC_TRACK() lazily when calling Python function.
Calling function is up to 5% faster.
---
This change is also correct. It's more that the change showed a bug which was hidden before.
It's just that now the garbage collector breaks the reference cycle differently since frames tracked differently by the GC.