- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 371
 
Closed
Description
consider:
import trio
import gc
class MyException(Exception):
    pass
async def demo():
    async def handle_error():
        try:
            raise MyException
        except MyException as e:
            exceptions.append(e)
    exceptions = []
    try:
        async with trio.open_nursery() as n:
            n.start_soon(handle_error)
        raise ExceptionGroup("errors", exceptions)
    finally:
        del exceptions
async def main():
    exc = None
    try:
        await demo()
    except* MyException as excs:
        exc = excs.exceptions[0]
    assert exc is not None
    print(gc.get_referrers(exc))
    exc.__traceback__.tb_frame.f_locals  # re-materialize f_locals to sync any deletions
    print(gc.get_referrers(exc))
trio.run(main)this prints:
[[MyException()]]
[]
so there's a reference cycle from the exc.__traceback__.tb_frame.f_locals["exceptions"][0] is exc, which gets cleared when you re-materialize f_locals
this is caused by this materialization of the frame f_locals
Line 1874 in 2a66a0d
| coro.cr_frame.f_locals.setdefault(LOCALS_KEY_KI_PROTECTION_ENABLED, system_task) | 
See also agronholm/anyio#809
Metadata
Metadata
Assignees
Labels
No labels