Message351083
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 |
|
Date |
User |
Action |
Args |
2019-09-03 12:45:01 | vstinner | set | recipients:
+ vstinner, pitrou, christian.heimes, petr.viktorin, lukasz.langa, Mark.Shannon, jdemeyer, pablogsal |
2019-09-03 12:45:01 | vstinner | set | messageid: <1567514701.35.0.255986681549.issue38006@roundup.psfhosted.org> |
2019-09-03 12:45:01 | vstinner | link | issue38006 messages |
2019-09-03 12:45:01 | vstinner | create | |
|