Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-122858: Deprecate asyncio.iscoroutinefunction #122875

Merged
merged 16 commits into from
Aug 11, 2024
2 changes: 1 addition & 1 deletion Doc/library/unittest.mock.rst
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ object::
call is an awaitable.

>>> mock = AsyncMock()
>>> asyncio.iscoroutinefunction(mock)
>>> inspect.iscoroutinefunction(mock)
True
>>> inspect.isawaitable(mock()) # doctest: +SKIP
True
Expand Down
5 changes: 5 additions & 0 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,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
Expand Down
2 changes: 1 addition & 1 deletion Lib/asyncio/base_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
9 changes: 9 additions & 0 deletions Lib/asyncio/coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion Lib/asyncio/unix_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_asyncio/test_pep492.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_asyncio/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -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
Expand All @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_unittest/testmock/testmagicmethods.py
Original file line number Diff line number Diff line change
@@ -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


Expand Down
4 changes: 2 additions & 2 deletions Lib/unittest/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Deprecate :func:`!asyncio.iscoroutinefunction` in favor of
:func:`inspect.iscoroutinefunction`.
Loading