New submission from Vojtěch Fried:
I have this test case:
import gc
import sys
import traceback
def hold_world():
try:
raise Exception("test1")
except Exception as exc:
print("exc caught in frame: ", exc.__traceback__.tb_frame)
assert not exc.__traceback__.tb_next
#exc.__traceback__ = None #ok
tmp = exc
traceback.clear_frames(exc.__traceback__) #not enough
def use_obj( o ):
hold_world()
#o = None #needed to get rid of the reference in the frame
def main():
o = ["survivor"]
print(gc.get_referrers(o))
print(sys.getrefcount(o)) #2
use_obj( o )
print(gc.get_referrers(o))
print(sys.getrefcount(o)) #3
#o = None #needed to get rid of the reference in the frame
if __name__ == '__main__':
main()
The outpus is:
[<frame object at 0x0000000001DA2630>]
2
exc caught in frame: <frame object at 0x0000000002206928>
[<frame object at 0x0000000001DA2630>, <frame object at 0x0000000002197B08>]
3
When either uncommenting the line "exc.__traceback__ = None" or uncommenting "o
= None" lines, the output is like
[<frame object at 0x0000000001DA2630>]
2
exc caught in frame: <frame object at 0x0000000002256928>
[<frame object at 0x0000000001DA2630>]
2
It seems that "hold_world" function somehow manages to (indirectly) add a
reference to "o" object. So "o" is not cleared at "main" end, but rather
garbage collected.
Even though there is a reference cycle tmp -> traceback -> frame -> tmp, the
frames outside "hold_world" should not be affected, but it looks like they are.
----------
components: Interpreter Core
messages: 298936
nosy: vojtechfried
priority: normal
severity: normal
status: open
title: caught and stored exception creates a reference cycle outside its
traceback
type: behavior
versions: Python 3.6
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue31005>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com