Skip to content

gh-122858: Deprecate asyncio.iscoroutinefunction #122875

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

Merged
merged 16 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 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
2 changes: 2 additions & 0 deletions Lib/test/test_asyncio/test_pep492.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import asyncio
from test.test_asyncio import utils as test_utils
from test.support.warnings_helper import ignore_warnings


def tearDownModule():
Expand Down Expand Up @@ -125,6 +126,7 @@ def foo(): yield
self.assertFalse(asyncio.iscoroutine(foo()))


@ignore_warnings(category=DeprecationWarning)
def test_iscoroutinefunction(self):
async def foo(): pass
self.assertTrue(asyncio.iscoroutinefunction(foo))
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
15 changes: 7 additions & 8 deletions Lib/unittest/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import sys
import builtins
import pkgutil
from asyncio import iscoroutinefunction
import threading
from types import CodeType, ModuleType, MethodType
from unittest.util import safe_repr
Expand All @@ -57,12 +56,12 @@ def _is_async_obj(obj):
return False
if hasattr(obj, '__func__'):
obj = getattr(obj, '__func__')
return iscoroutinefunction(obj) or inspect.isawaitable(obj)
return inspect.iscoroutinefunction(obj) or inspect.isawaitable(obj)


def _is_async_func(func):
if getattr(func, '__code__', None):
return iscoroutinefunction(func)
return inspect.iscoroutinefunction(func)
else:
return False

Expand Down Expand Up @@ -556,7 +555,7 @@ def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False,
unwrapped_attr = inspect.unwrap(unwrapped_attr)
except ValueError:
pass
if iscoroutinefunction(unwrapped_attr):
if inspect.iscoroutinefunction(unwrapped_attr):
_spec_asyncs.append(attr)

spec = spec_list
Expand Down Expand Up @@ -2307,7 +2306,7 @@ async def _execute_mock_call(self, /, *args, **kwargs):
raise StopAsyncIteration
if _is_exception(result):
raise result
elif iscoroutinefunction(effect):
elif inspect.iscoroutinefunction(effect):
result = await effect(*args, **kwargs)
else:
result = effect(*args, **kwargs)
Expand All @@ -2319,7 +2318,7 @@ async def _execute_mock_call(self, /, *args, **kwargs):
return self.return_value

if self._mock_wraps is not None:
if iscoroutinefunction(self._mock_wraps):
if inspect.iscoroutinefunction(self._mock_wraps):
return await self._mock_wraps(*args, **kwargs)
return self._mock_wraps(*args, **kwargs)

Expand Down Expand Up @@ -2456,7 +2455,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 Expand Up @@ -2838,7 +2837,7 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,

skipfirst = _must_skip(spec, entry, is_type)
child_kwargs['_eat_self'] = skipfirst
if iscoroutinefunction(original):
if inspect.iscoroutinefunction(original):
child_klass = AsyncMock
else:
child_klass = MagicMock
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