STINNER Victor <vstin...@python.org> added the comment:
Second step: when func_clear() is called, the closure is cleared. Clearing the closure should call the function which is being cleared (or is already cleared). --- import gc class CallFunc: def __del__(self): func = self.func if func is None: return print("CallFunc", func) func("call func from CallFunc.__del__") def create_remove(): call_func = CallFunc() def remove(msg): x = call_func print(msg) remove.__name__ = "evil_func" call_func.func = remove return call_func, remove call_func, remove = create_remove() print("== clear ==") call_func = None remove = None print() print("== collect ==") gc.collect() print() print("== exit ==") --- Output (with my hacked CPython): ------------------ == clear == == collect == CallFunc <function create_remove.<locals>.remove at 0x7fab8a189eb0> call func from CallFunc.__del__ func_clear remove() -- in delete_garbage? 1 == exit == ------------------ call_func and remove are part of a reference cycle. A forced garbage collection breaks the cycle and removes the two objects, but they are not removed in the expected order: * first: call_func * then: remove The crash requires to destroy the objects in the reverse order ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue38006> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com