Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Description
Bug report
CPython uses freelists to speed up allocation of certain frequently allocated types of objects. CPython also supports finalizers (i.e.,tp_finalize) that are only called once, even if the object is resurrected by its finalizer. These two features do not work well together as currently implemented because we don't clear the_PyGC_PREV_MASK_FINALIZED bit when objects are allocated from free-lists.
As far as I can tell, this only affectsPyAsyncGenASend objects -- I haven't seen other objects that are both allocated from free-lists and usetp_finalize.
The finalizer forPyAsyncGenASend (which may issue a warning), may not be called if the object is allocated from a free-list (and already finalized):
Test case
Thetest(False) call should issue a warning about unawaited "asend" coroutine. However, the presence of thetest(true) call will suppress this warning (if uncommented) because it ensures that there is an already-finalized object in the free-list.
importasynciodefmain():loop=asyncio.new_event_loop()asyncdefgen():yield1asyncdeftest(do_await):g=gen()ifdo_await:r=awaitg.asend(None)else:g.asend(None)awaitg.aclose()# Uncommenting this line prevents the warning on the following call# due to the already finalized PyAsyncGenASend object in the free-list.# loop.run_until_complete(test(True))# This should warn!loop.run_until_complete(test(False))loop.close()if__name__=='__main__':main()
Linked PRs
Metadata
Metadata
Assignees
Labels
Projects
Status