Created
January 12, 2022 20:11
-
-
Save Bibo-Joshi/96f6b4642d749664145d429e386fb215 to your computer and use it in GitHub Desktop.
Wrapper around `asyncio.iscoroutinefunction` that handles `functools.partial` on Python<=3.7 and also async `__call__` methods
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import asyncio | |
| import sys | |
| from functools import partial | |
| if sys.version_info >= (3, 8): | |
| _MANUAL_UNWRAP = False | |
| else: | |
| _MANUAL_UNWRAP = True | |
| def is_coroutine_function(obj: object) -> bool: | |
| """Thin wrapper around :func:`asyncio.iscoroutinefunction` that handles the support for | |
| :func:`functools.partial` which :func:`asyncio.iscoroutinefunction` only natively supports in | |
| Python 3.8+. Also handles callable classes, where ``__call__`` is async. | |
| Note: | |
| Can be removed once support for Python 3.7 is dropped. | |
| Args: | |
| obj (:class:`object`): The object to test. | |
| Returns: | |
| :obj:`bool`: Whether or not the object is a | |
| `coroutine function <https://docs.python.org/3/library/asyncio-task.html#coroutine>` | |
| """ | |
| if not callable(obj): | |
| return False | |
| if _MANUAL_UNWRAP: | |
| while isinstance(obj, partial): | |
| obj = obj.func # type: ignore[attr-defined] | |
| if not callable(obj): | |
| return False | |
| return asyncio.iscoroutinefunction(obj) or ( | |
| hasattr(obj, "__call__") and asyncio.iscoroutinefunction(obj.__call__) | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment