Skip to content

Breaking API Change in Python 3.13.3: Task Factory Signature Change #133745

Open
@pablogsal

Description

@pablogsal

In PR #128768 (gh-128308), the asyncio task factory signature was changed from (loop, coro, context=None) to (loop, coro, **kwargs). This seemingly minor change breaks backward compatibility for existing task factory implementations.

The documentation was updated to reflect this new contract:

  • Old: (loop, coro, context=None), where the callable must return a asyncio.Future-compatible object.
  • New: (loop, coro, **kwargs), where the callable must pass on all *kwargs, and return a asyncio.Task-compatible object.

This change causes runtime errors for any code with task factories implemented according to the previous contract, as these factories now unexpectedly receive keyword arguments like name that they aren't designed to handle.

Reproducer

import asyncio

# Task factory implemented according to the previous API contract
def old_style_task_factory(loop, coro, context=None):
    print(f"Creating task with loop={loop}, coro={coro}, context={context}")
    return asyncio.Task(coro, loop=loop)

async def main():
    # Set up a custom task factory following the old documented API
    loop = asyncio.get_event_loop()
    loop.set_task_factory(old_style_task_factory)
    
    # This will fail with TypeError due to unexpected 'name' argument
    print("Attempting to create task with name...")
    await loop.create_task(asyncio.sleep(0.1), name="test_task")
    print("Task completed successfully")  # We won't reach this line

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except TypeError as e:
        print(f"ERROR: {e}")
        # Output: ERROR: old_style_task_factory() got an unexpected keyword argument 'name'

This prints:

Attempting to create task with name...
Creating task with loop=<_UnixSelectorEventLoop running=False closed=False debug=False>, coro=<coroutine object BaseEventLoop.shutdown_asyncgens at 0x72b413aa5450>, context=None
Creating task with loop=<_UnixSelectorEventLoop running=False closed=False debug=False>, coro=<coroutine object BaseEventLoop.shutdown_default_executor at 0x72b413cc5910>, context=None
ERROR: old_style_task_factory() got an unexpected keyword argument 'name'
<sys>:0: RuntimeWarning: coroutine 'sleep' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

This is a breaking change introduced in a patch release, which violates our versioning policy. The change was intended to support the name keyword argument for eager tasks, but the implementation method has unintentionally broken existing code that followed the previously documented API contract.

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Metadata

Metadata

Labels

3.13bugs and security fixes3.14bugs and security fixes3.15new features, bugs and security fixesrelease-blockerstdlibPython modules in the Lib dirtopic-asynciotype-bugAn unexpected behavior, bug, or error

Projects

Status

Todo

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions