diff --git a/sentry_sdk/integrations/asyncio.py b/sentry_sdk/integrations/asyncio.py index 66742fe6e4..a652edc280 100644 --- a/sentry_sdk/integrations/asyncio.py +++ b/sentry_sdk/integrations/asyncio.py @@ -1,4 +1,5 @@ import sys +import functools import sentry_sdk from sentry_sdk.consts import OP @@ -14,11 +15,13 @@ from typing import cast, TYPE_CHECKING if TYPE_CHECKING: - from typing import Any + from typing import Any, Callable, TypeVar from collections.abc import Coroutine from sentry_sdk._types import ExcInfo + T = TypeVar("T", bound=Callable[..., Any]) + def get_name(coro): # type: (Any) -> str @@ -29,6 +32,17 @@ def get_name(coro): ) +def _wrap_coroutine(wrapped): + # type: (Coroutine[Any, Any, Any]) -> Callable[[T], T] + # Only __name__ and __qualname__ are copied from function to coroutine in CPython + return functools.partial( + functools.update_wrapper, + wrapped=wrapped, # type: ignore + assigned=("__name__", "__qualname__"), + updated=(), + ) + + def patch_asyncio(): # type: () -> None orig_task_factory = None @@ -39,6 +53,7 @@ def patch_asyncio(): def _sentry_task_factory(loop, coro, **kwargs): # type: (asyncio.AbstractEventLoop, Coroutine[Any, Any, Any], Any) -> asyncio.Future[Any] + @_wrap_coroutine(coro) async def _task_with_sentry_span_creation(): # type: () -> Any result = None diff --git a/tests/integrations/asyncio/test_asyncio.py b/tests/integrations/asyncio/test_asyncio.py index 66113746bf..11b60fb0e1 100644 --- a/tests/integrations/asyncio/test_asyncio.py +++ b/tests/integrations/asyncio/test_asyncio.py @@ -67,7 +67,16 @@ async def test_create_task( with sentry_sdk.start_transaction(name="test_transaction_for_create_task"): with sentry_sdk.start_span(op="root", name="not so important"): - tasks = [asyncio.create_task(foo()), asyncio.create_task(bar())] + foo_task = asyncio.create_task(foo()) + bar_task = asyncio.create_task(bar()) + + if hasattr(foo_task.get_coro(), "__name__"): + assert foo_task.get_coro().__name__ == "foo" + if hasattr(bar_task.get_coro(), "__name__"): + assert bar_task.get_coro().__name__ == "bar" + + tasks = [foo_task, bar_task] + await asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION) sentry_sdk.flush()