Skip to content

Commit d0223fb

Browse files
Fix the default TaskHandle name for start() on Trio
The Trio backend computed final_name from func for the nursery, but built the TaskHandle from the raw name argument, which is None by default. The handle then derived its name from the internal wrapper coroutine instead of func, so it lost the module qualifier and did not match the task's own name. The asyncio backend already spawns the handle with final_name, so the two backends disagreed: asyncio TaskHandle.name = '__main__.taskfunc' (matches TaskInfo) trio TaskHandle.name = 'taskfunc' (does not) Build the handle from final_name too. An explicit name argument was already honoured and is unaffected. Closes #1231
1 parent 2ba69a6 commit d0223fb

3 files changed

Lines changed: 49 additions & 2 deletions

File tree

docs/versionhistory.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ Version history
33

44
This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.
55

6+
**UNRELEASED**
7+
8+
- Fixed the default ``TaskHandle.name`` of a task started with ``TaskGroup.start()`` on
9+
Trio being taken from the internal wrapper coroutine, so it lacked the module
10+
qualifier and disagreed with the task's own name
11+
(`#1231 <https://github.com/agronholm/anyio/issues/1231>`_)
12+
613
**4.14.2**
714

815
- Changed ``ByteReceiveStream.receive()`` implementations to raise a ``ValueError`` when

src/anyio/_backends/_trio.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,11 @@ async def start(
286286
) -> Any:
287287
handle: TaskHandle[T_co]
288288

289+
# Derived from func, not from the wrapper coroutine the handle is built
290+
# around, so that TaskHandle.name matches the task's own name (and the
291+
# asyncio backend, which spawns with this same name).
292+
final_name = get_callable_name(func, name)
293+
289294
async def run_coro_with_task_status(
290295
*, task_status: trio.TaskStatus[Any]
291296
) -> None:
@@ -297,11 +302,10 @@ async def run_coro_with_task_status(
297302
else:
298303
wrapper_task_status.real_task_status = task_status
299304

300-
handle = TaskHandle(coro, name)
305+
handle = TaskHandle(coro, final_name)
301306
await handle._run_coro()
302307

303308
self._check_active()
304-
final_name = get_callable_name(func, name)
305309
start_value = await self._nursery.start(
306310
run_coro_with_task_status, name=final_name
307311
)

tests/test_taskgroups.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,42 @@ async def taskfunc(*, task_status: TaskStatus[int]) -> int:
18271827
assert handle.start_value == 3
18281828

18291829

1830+
async def test_start_name_default() -> None:
1831+
"""Like ``TestCreateTask.test_task_name_default``, but for ``start()``.
1832+
1833+
The handle used to be named after the wrapper coroutine on Trio, which
1834+
dropped the module qualifier and disagreed with the task's own name.
1835+
"""
1836+
1837+
async def taskfunc(*, task_status: TaskStatus[None]) -> str | None:
1838+
task_status.started()
1839+
return get_current_task().name
1840+
1841+
expected = f"{__name__}.test_start_name_default.<locals>.taskfunc"
1842+
async with create_task_group() as tg:
1843+
handle = await tg.start(taskfunc, return_handle=True)
1844+
assert re.match(
1845+
rf"<TaskHandle (pending|finished) name='{re.escape(expected)}' "
1846+
r"coro=<coroutine object(.+)>>",
1847+
repr(handle),
1848+
)
1849+
assert await handle == handle.name
1850+
1851+
assert handle.name == expected
1852+
1853+
1854+
async def test_start_name_custom_name() -> None:
1855+
async def taskfunc(*, task_status: TaskStatus[None]) -> str | None:
1856+
task_status.started()
1857+
return get_current_task().name
1858+
1859+
async with create_task_group() as tg:
1860+
handle = await tg.start(taskfunc, name="custom name", return_handle=True)
1861+
assert await handle == "custom name"
1862+
1863+
assert handle.name == "custom name"
1864+
1865+
18301866
@pytest.mark.skipif(
18311867
sys.implementation.name == "pypy",
18321868
reason=(

0 commit comments

Comments
 (0)