mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-84753: Make inspect.iscoroutinefunction() work with AsyncMock (GH-94050) (GH-94460)
The inspect version was not working with unittest.mock.AsyncMock.
The fix introduces special-casing of AsyncMock in
`inspect.iscoroutinefunction` equivalent to the one
performed in `asyncio.iscoroutinefunction`.
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
(cherry picked from commit 4261b6bffc
)
Co-authored-by: Mehdi ABAAKOUK <sileht@sileht.net>
This commit is contained in:
parent
7fe949e5ea
commit
9ebec7d46c
5 changed files with 23 additions and 1 deletions
|
@ -395,7 +395,7 @@ def _has_code_flag(f, flag):
|
||||||
while ismethod(f):
|
while ismethod(f):
|
||||||
f = f.__func__
|
f = f.__func__
|
||||||
f = functools._unwrap_partial(f)
|
f = functools._unwrap_partial(f)
|
||||||
if not isfunction(f):
|
if not (isfunction(f) or _signature_is_functionlike(f)):
|
||||||
return False
|
return False
|
||||||
return bool(f.__code__.co_flags & flag)
|
return bool(f.__code__.co_flags & flag)
|
||||||
|
|
||||||
|
|
|
@ -1653,6 +1653,7 @@ class BaseTaskTests:
|
||||||
self.assertTrue(asyncio.iscoroutinefunction(fn2))
|
self.assertTrue(asyncio.iscoroutinefunction(fn2))
|
||||||
|
|
||||||
self.assertFalse(asyncio.iscoroutinefunction(mock.Mock()))
|
self.assertFalse(asyncio.iscoroutinefunction(mock.Mock()))
|
||||||
|
self.assertTrue(asyncio.iscoroutinefunction(mock.AsyncMock()))
|
||||||
|
|
||||||
def test_coroutine_non_gen_function(self):
|
def test_coroutine_non_gen_function(self):
|
||||||
async def func():
|
async def func():
|
||||||
|
|
|
@ -202,6 +202,10 @@ class TestPredicates(IsTestBase):
|
||||||
gen_coroutine_function_example))))
|
gen_coroutine_function_example))))
|
||||||
self.assertTrue(inspect.isgenerator(gen_coro))
|
self.assertTrue(inspect.isgenerator(gen_coro))
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
inspect.iscoroutinefunction(unittest.mock.Mock()))
|
||||||
|
self.assertTrue(
|
||||||
|
inspect.iscoroutinefunction(unittest.mock.AsyncMock()))
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
inspect.iscoroutinefunction(coroutine_function_example))
|
inspect.iscoroutinefunction(coroutine_function_example))
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
|
@ -210,6 +214,10 @@ class TestPredicates(IsTestBase):
|
||||||
coroutine_function_example))))
|
coroutine_function_example))))
|
||||||
self.assertTrue(inspect.iscoroutine(coro))
|
self.assertTrue(inspect.iscoroutine(coro))
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
inspect.isgeneratorfunction(unittest.mock.Mock()))
|
||||||
|
self.assertFalse(
|
||||||
|
inspect.isgeneratorfunction(unittest.mock.AsyncMock()))
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
inspect.isgeneratorfunction(coroutine_function_example))
|
inspect.isgeneratorfunction(coroutine_function_example))
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
|
@ -218,6 +226,12 @@ class TestPredicates(IsTestBase):
|
||||||
coroutine_function_example))))
|
coroutine_function_example))))
|
||||||
self.assertFalse(inspect.isgenerator(coro))
|
self.assertFalse(inspect.isgenerator(coro))
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
inspect.isasyncgenfunction(unittest.mock.Mock()))
|
||||||
|
self.assertFalse(
|
||||||
|
inspect.isasyncgenfunction(unittest.mock.AsyncMock()))
|
||||||
|
self.assertFalse(
|
||||||
|
inspect.isasyncgenfunction(coroutine_function_example))
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
inspect.isasyncgenfunction(async_generator_function_example))
|
inspect.isasyncgenfunction(async_generator_function_example))
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
|
|
|
@ -2175,6 +2175,10 @@ class AsyncMockMixin(Base):
|
||||||
code_mock = NonCallableMock(spec_set=CodeType)
|
code_mock = NonCallableMock(spec_set=CodeType)
|
||||||
code_mock.co_flags = inspect.CO_COROUTINE
|
code_mock.co_flags = inspect.CO_COROUTINE
|
||||||
self.__dict__['__code__'] = code_mock
|
self.__dict__['__code__'] = code_mock
|
||||||
|
self.__dict__['__name__'] = 'AsyncMock'
|
||||||
|
self.__dict__['__defaults__'] = tuple()
|
||||||
|
self.__dict__['__kwdefaults__'] = {}
|
||||||
|
self.__dict__['__annotations__'] = None
|
||||||
|
|
||||||
async def _execute_mock_call(self, /, *args, **kwargs):
|
async def _execute_mock_call(self, /, *args, **kwargs):
|
||||||
# This is nearly just like super(), except for special handling
|
# This is nearly just like super(), except for special handling
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
:func:`inspect.iscoroutinefunction` now properly returns ``True`` when an instance
|
||||||
|
of :class:`unittest.mock.AsyncMock` is passed to it. This makes it consistent with
|
||||||
|
behavior of :func:`asyncio.iscoroutinefunction`. Patch by Mehdi ABAAKOUK.
|
Loading…
Add table
Add a link
Reference in a new issue