From 01f24b7bb17c860db775f983cefc0cb121c83c40 Mon Sep 17 00:00:00 2001 From: SAY-5 Date: Mon, 11 May 2026 19:20:45 -0700 Subject: [PATCH] fix(tasks): use inspect.iscoroutinefunction for Python 3.14 compatibility asyncio.iscoroutinefunction is deprecated in Python 3.14 and emits a DeprecationWarning. inspect.iscoroutinefunction is the recommended replacement and is equivalent on Python 3.12+ (asyncio.coroutine was removed in 3.12). Closes #373 Signed-off-by: SAY-5 --- fastapi_utils/tasks.py | 5 +++-- tests/test_tasks_iscoroutine_regression.py | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/test_tasks_iscoroutine_regression.py diff --git a/fastapi_utils/tasks.py b/fastapi_utils/tasks.py index 5c83f65..334b325 100644 --- a/fastapi_utils/tasks.py +++ b/fastapi_utils/tasks.py @@ -1,6 +1,7 @@ from __future__ import annotations import asyncio +import inspect import logging import warnings from functools import wraps @@ -19,7 +20,7 @@ async def _handle_func(func: NoArgsNoReturnAnyFuncT) -> None: - if asyncio.iscoroutinefunction(func): + if inspect.iscoroutinefunction(func): await func() else: await run_in_threadpool(func) @@ -27,7 +28,7 @@ async def _handle_func(func: NoArgsNoReturnAnyFuncT) -> None: async def _handle_exc(exc: Exception, on_exception: ExcArgNoReturnAnyFuncT | None) -> None: if on_exception: - if asyncio.iscoroutinefunction(on_exception): + if inspect.iscoroutinefunction(on_exception): await on_exception(exc) else: await run_in_threadpool(on_exception, exc) diff --git a/tests/test_tasks_iscoroutine_regression.py b/tests/test_tasks_iscoroutine_regression.py new file mode 100644 index 0000000..0612321 --- /dev/null +++ b/tests/test_tasks_iscoroutine_regression.py @@ -0,0 +1,20 @@ +"""Regression tests for issue #373. + +The tasks module must use ``inspect.iscoroutinefunction`` rather than +``asyncio.iscoroutinefunction``, which is deprecated in Python 3.14 +(``DeprecationWarning``) and scheduled for removal. + +See: https://github.com/fastapiutils/fastapi-utils/issues/373 +""" + +from __future__ import annotations + +import inspect + +from fastapi_utils import tasks as tasks_module + + +def test_tasks_module_uses_inspect_iscoroutinefunction() -> None: + source = inspect.getsource(tasks_module) + assert "asyncio.iscoroutinefunction" not in source + assert "inspect.iscoroutinefunction" in source