Skip to content

Commit

Permalink
support partials in asyncio.iscoroutinefunction
Browse files Browse the repository at this point in the history
  • Loading branch information
graingert committed Jul 16, 2022
1 parent 2e9da8e commit 1c0cf0a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
7 changes: 5 additions & 2 deletions Lib/asyncio/coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ def _is_debug_mode():

def iscoroutinefunction(func):
"""Return True if func is a decorated coroutine function."""
return (inspect.iscoroutinefunction(func) or
getattr(func, '_is_coroutine', None) is _is_coroutine)
return (
inspect.iscoroutinefunction(func)
or getattr(func, '_is_coroutine', None) is _is_coroutine
or getattr(functools._unwrap_partial(func), "_is_coroutine", None) is _is_coroutine
)


# Prioritize native coroutine check to speed-up
Expand Down
20 changes: 19 additions & 1 deletion Lib/test/test_asyncio/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1644,9 +1644,27 @@ def fn1():
yield
self.assertFalse(asyncio.iscoroutinefunction(fn1))

async def fn2():
def fn2():
pass

fn2._is_coroutine = asyncio.coroutines._is_coroutine

self.assertTrue(asyncio.iscoroutinefunction(fn2))
self.assertTrue(asyncio.iscoroutinefunction(functools.partial(fn2)))
self.assertTrue(asyncio.iscoroutinefunction(functools.partial(functools.partial(fn2))))

async def async_fn():
pass

self.assertTrue(asyncio.iscoroutinefunction(afn2))

def sync_fn():
pass

partial_sync_fn = functools.partial(sync_fn)
partial_sync_fn._is_coroutine = asyncio.coroutines._is_coroutine

self.assertTrue(asyncio.iscoroutinefunction(partial_sync_fn))

self.assertFalse(asyncio.iscoroutinefunction(mock.Mock()))
self.assertTrue(asyncio.iscoroutinefunction(mock.AsyncMock()))
Expand Down

0 comments on commit 1c0cf0a

Please sign in to comment.