Message298936
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. |
|
Date |
User |
Action |
Args |
2017-07-24 09:05:19 | vojtechfried | set | recipients:
+ vojtechfried |
2017-07-24 09:05:19 | vojtechfried | set | messageid: <1500887119.8.0.911984158836.issue31005@psf.upfronthosting.co.za> |
2017-07-24 09:05:19 | vojtechfried | link | issue31005 messages |
2017-07-24 09:05:19 | vojtechfried | create | |
|