gh-122858: Deprecate `asyncio.iscoroutinefunction` (#122875)
Deprecate `asyncio.iscoroutinefunction` in favor of `inspect.iscoroutinefunction`.
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
index 757277e..e15f8a4 100644
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -882,7 +882,7 @@
call is an awaitable.
>>> mock = AsyncMock()
- >>> asyncio.iscoroutinefunction(mock)
+ >>> inspect.iscoroutinefunction(mock)
True
>>> inspect.isawaitable(mock()) # doctest: +SKIP
True
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index a7c817c..27594c3 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -434,6 +434,11 @@
:c:macro:`!isfinite` available from :file:`math.h`
since C99. (Contributed by Sergey B Kirpichev in :gh:`119613`.)
+* :func:`!asyncio.iscoroutinefunction` is deprecated
+ and will be removed in Python 3.16,
+ use :func:`inspect.iscoroutinefunction` instead.
+ (Contributed by Jiahao Li and Kumar Aditya in :gh:`122875`.)
+
.. Add deprecations above alphabetically, not here at the end.
.. include:: ../deprecations/c-api-pending-removal-in-3.15.rst
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index e4a39f4..000647f 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -837,7 +837,7 @@ def call_soon(self, callback, *args, context=None):
def _check_callback(self, callback, method):
if (coroutines.iscoroutine(callback) or
- coroutines.iscoroutinefunction(callback)):
+ coroutines._iscoroutinefunction(callback)):
raise TypeError(
f"coroutines cannot be used with {method}()")
if not callable(callback):
diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py
index ab4f30e..a51319c 100644
--- a/Lib/asyncio/coroutines.py
+++ b/Lib/asyncio/coroutines.py
@@ -18,7 +18,16 @@ def _is_debug_mode():
def iscoroutinefunction(func):
+ import warnings
"""Return True if func is a decorated coroutine function."""
+ warnings._deprecated("asyncio.iscoroutinefunction",
+ f"{warnings._DEPRECATED_MSG}; "
+ "use inspect.iscoroutinefunction() instead",
+ remove=(3,16))
+ return _iscoroutinefunction(func)
+
+
+def _iscoroutinefunction(func):
return (inspect.iscoroutinefunction(func) or
getattr(func, '_is_coroutine', None) is _is_coroutine)
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 2796e39..0227eb5 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -95,7 +95,7 @@ def add_signal_handler(self, sig, callback, *args):
Raise RuntimeError if there is a problem setting up the handler.
"""
if (coroutines.iscoroutine(callback) or
- coroutines.iscoroutinefunction(callback)):
+ coroutines._iscoroutinefunction(callback)):
raise TypeError("coroutines cannot be used "
"with add_signal_handler()")
self._check_signal(sig)
diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py
index 033784b..84c5f99 100644
--- a/Lib/test/test_asyncio/test_pep492.py
+++ b/Lib/test/test_asyncio/test_pep492.py
@@ -124,10 +124,10 @@ def foo(): yield
self.assertFalse(asyncio.iscoroutine(foo()))
-
def test_iscoroutinefunction(self):
async def foo(): pass
- self.assertTrue(asyncio.iscoroutinefunction(foo))
+ with self.assertWarns(DeprecationWarning):
+ self.assertTrue(asyncio.iscoroutinefunction(foo))
def test_async_def_coroutines(self):
async def bar():
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 9b22fb9..a1013ab 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -20,6 +20,7 @@
from test.test_asyncio import utils as test_utils
from test import support
from test.support.script_helper import assert_python_ok
+from test.support.warnings_helper import ignore_warnings
def tearDownModule():
@@ -1939,6 +1940,7 @@ async def notmutch():
self.assertFalse(task.cancelled())
self.assertIs(task.exception(), base_exc)
+ @ignore_warnings(category=DeprecationWarning)
def test_iscoroutinefunction(self):
def fn():
pass
@@ -1956,6 +1958,7 @@ async def fn2():
self.assertFalse(asyncio.iscoroutinefunction(mock.Mock()))
self.assertTrue(asyncio.iscoroutinefunction(mock.AsyncMock()))
+ @ignore_warnings(category=DeprecationWarning)
def test_coroutine_non_gen_function(self):
async def func():
return 'test'
diff --git a/Lib/test/test_unittest/testmock/testmagicmethods.py b/Lib/test/test_unittest/testmock/testmagicmethods.py
index a4feae7..5ca753b 100644
--- a/Lib/test/test_unittest/testmock/testmagicmethods.py
+++ b/Lib/test/test_unittest/testmock/testmagicmethods.py
@@ -1,7 +1,7 @@
import math
import unittest
import os
-from asyncio import iscoroutinefunction
+from inspect import iscoroutinefunction
from unittest.mock import AsyncMock, Mock, MagicMock, _magics
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 2bbbcf4..480c85b 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -32,7 +32,7 @@
import sys
import builtins
import pkgutil
-from asyncio import iscoroutinefunction
+from inspect import iscoroutinefunction
import threading
from types import CodeType, ModuleType, MethodType
from unittest.util import safe_repr
@@ -2456,7 +2456,7 @@ class AsyncMock(AsyncMockMixin, AsyncMagicMixin, Mock):
recognized as an async function, and the result of a call is an awaitable:
>>> mock = AsyncMock()
- >>> iscoroutinefunction(mock)
+ >>> inspect.iscoroutinefunction(mock)
True
>>> inspect.isawaitable(mock())
True
diff --git a/Misc/NEWS.d/next/Library/2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst b/Misc/NEWS.d/next/Library/2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst
new file mode 100644
index 0000000..d452ad6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst
@@ -0,0 +1,2 @@
+Deprecate :func:`!asyncio.iscoroutinefunction` in favor of
+:func:`inspect.iscoroutinefunction`.