Skip to content

Commit 1c0cf0a

Browse files
committed
support partials in asyncio.iscoroutinefunction
1 parent 2e9da8e commit 1c0cf0a

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

Lib/asyncio/coroutines.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ def _is_debug_mode():
1919

2020
def iscoroutinefunction(func):
2121
"""Return True if func is a decorated coroutine function."""
22-
return (inspect.iscoroutinefunction(func) or
23-
getattr(func, '_is_coroutine', None) is _is_coroutine)
22+
return (
23+
inspect.iscoroutinefunction(func)
24+
or getattr(func, '_is_coroutine', None) is _is_coroutine
25+
or getattr(functools._unwrap_partial(func), "_is_coroutine", None) is _is_coroutine
26+
)
2427

2528

2629
# Prioritize native coroutine check to speed-up

Lib/test/test_asyncio/test_tasks.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -1644,9 +1644,27 @@ def fn1():
16441644
yield
16451645
self.assertFalse(asyncio.iscoroutinefunction(fn1))
16461646

1647-
async def fn2():
1647+
def fn2():
16481648
pass
1649+
1650+
fn2._is_coroutine = asyncio.coroutines._is_coroutine
1651+
16491652
self.assertTrue(asyncio.iscoroutinefunction(fn2))
1653+
self.assertTrue(asyncio.iscoroutinefunction(functools.partial(fn2)))
1654+
self.assertTrue(asyncio.iscoroutinefunction(functools.partial(functools.partial(fn2))))
1655+
1656+
async def async_fn():
1657+
pass
1658+
1659+
self.assertTrue(asyncio.iscoroutinefunction(afn2))
1660+
1661+
def sync_fn():
1662+
pass
1663+
1664+
partial_sync_fn = functools.partial(sync_fn)
1665+
partial_sync_fn._is_coroutine = asyncio.coroutines._is_coroutine
1666+
1667+
self.assertTrue(asyncio.iscoroutinefunction(partial_sync_fn))
16501668

16511669
self.assertFalse(asyncio.iscoroutinefunction(mock.Mock()))
16521670
self.assertTrue(asyncio.iscoroutinefunction(mock.AsyncMock()))

0 commit comments

Comments
 (0)