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 <rep...@bugs.python.org> <http://bugs.python.org/issue31005> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com