Skip to content

PyAsyncGenASend objects allocated from freelists may not have their finalizers called #113753

Closed
@colesbury

Description

@colesbury

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 affects PyAsyncGenASend objects -- I haven't seen other objects that are both allocated from free-lists and use tp_finalize.

The finalizer for PyAsyncGenASend (which may issue a warning), may not be called if the object is allocated from a free-list (and already finalized):

Test case

The test(False) call should issue a warning about unawaited "asend" coroutine. However, the presence of the test(true) call will suppress this warning (if uncommented) because it ensures that there is an already-finalized object in the free-list.

import asyncio def main(): loop = asyncio.new_event_loop() async def gen(): yield 1 async def test(do_await): g = gen() if do_await: r = await g.asend(None) else: g.asend(None) await g.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

No one assigned

    Labels

    3.13bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)topic-asynciotype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions