Description
Bug report
Bug description:
Code below illustrate a behavior change in 3.13 which I believe is a bug, which "Task-2" the task name becomes "None" while calling asyncio.current_task().get_name()
import asyncio
def task_factory(loop, *args, **kwargs):
new_task = asyncio.Task(*args, **kwargs)
name = new_task.get_name()
# Python 3.9 to 3.13 prints name='Task-2'
# 'Task-3' and 'Task-4' is also printed because loop is shutting down, which is not in the scope of (possible) bug
print(f"{name=}")
return new_task
async def print_task_name():
current_task = asyncio.current_task()
name = current_task.get_name()
# Python 3.13 prints name='None' (but why does it print 'Task-2' before it's returned from task_factory() ?)
# Python 3.9 to 3.12 prints name='Task-2'
print(f"{name=}")
async def main():
loop = asyncio.get_running_loop()
loop.set_task_factory(task_factory)
new_task = asyncio.create_task(print_task_name())
await new_task
asyncio.run(main())
The source of bug/behavior change is that https://github.com/python/cpython/blob/v3.13.2/Lib/asyncio/base_events.py#L478 a set_name() is called unconditionally and version before 3.13 (e.g. https://github.com/python/cpython/blob/v3.12.9/Lib/asyncio/tasks.py#L70 ) setting task name to None does nothing which avoided the issue with custom task factory setting it's own task name.
If using a task factory, the task name can't be generated by task factory because it gets rewritten to name provided by asyncio.create_task(), which I think most people doesn't provide one.
Suggestion: check if name parameter is None before overwriting task name in create_task(), otherwise keep task name generated by task factory, and probably pass "name" parameter to task factory.
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Metadata
Metadata
Assignees
Projects
Status