From bc9d92c67933917b474e61905451c6408c68e71d Mon Sep 17 00:00:00 2001 From: Wulian <1055917385@qq.com> Date: Mon, 12 Aug 2024 00:35:51 +0800 Subject: [PATCH] gh-122858: Deprecate `asyncio.iscoroutinefunction` (#122875) Deprecate `asyncio.iscoroutinefunction` in favor of `inspect.iscoroutinefunction`. Co-authored-by: Kumar Aditya --- Doc/library/unittest.mock.rst | 2 +- Doc/whatsnew/3.14.rst | 5 +++++ Lib/asyncio/base_events.py | 2 +- Lib/asyncio/coroutines.py | 9 +++++++++ Lib/asyncio/unix_events.py | 2 +- Lib/test/test_asyncio/test_pep492.py | 4 ++-- Lib/test/test_asyncio/test_tasks.py | 3 +++ Lib/test/test_unittest/testmock/testmagicmethods.py | 2 +- Lib/unittest/mock.py | 4 ++-- .../2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst | 2 ++ 10 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-08-10-10-21-44.gh-issue-122858.ZC1rJD.rst diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 757277e102d..e15f8a4e903 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -882,7 +882,7 @@ object:: 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 a7c817c47d6..27594c3dea8 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -434,6 +434,11 @@ Deprecated :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 e4a39f4d345..000647f57dd 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -837,7 +837,7 @@ class BaseEventLoop(events.AbstractEventLoop): 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 ab4f30eb51b..a51319cb72a 100644 --- a/Lib/asyncio/coroutines.py +++ b/Lib/asyncio/coroutines.py @@ -18,7 +18,16 @@ _is_coroutine = object() 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 2796e397c0e..0227eb506c6 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -95,7 +95,7 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): 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 033784bc7ae..84c5f991295 100644 --- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -124,10 +124,10 @@ class CoroutineTests(BaseTest): 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 9b22fb942c6..a1013ab8033 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -20,6 +20,7 @@ from asyncio import tasks 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 @@ class BaseTaskTests: 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 @@ class BaseTaskTests: 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 a4feae7e9d3..5ca753b8f20 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 2bbbcf40e21..480c85bed9b 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -32,7 +32,7 @@ import pprint 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 00000000000..d452ad6a4f6 --- /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`.