diff options
author | Carlton Gibson <carlton@noumenal.es> | 2022-12-18 19:13:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-18 19:13:24 (GMT) |
commit | 532aa4e4e019812d0388920768ede7c04232ebe1 (patch) | |
tree | bac6a6c3f467bc6a7d7ac1210fc5f9929cc2742a /Lib/inspect.py | |
parent | 1cf3d78c92eb07dc09d15cc2e773b0b1b9436825 (diff) | |
download | cpython-532aa4e4e019812d0388920768ede7c04232ebe1.zip cpython-532aa4e4e019812d0388920768ede7c04232ebe1.tar.gz cpython-532aa4e4e019812d0388920768ede7c04232ebe1.tar.bz2 |
gh-94912: Added marker for non-standard coroutine function detection (#99247)
This introduces a new decorator `@inspect.markcoroutinefunction`,
which, applied to a sync function, makes it appear async to
`inspect.iscoroutinefunction()`.
Diffstat (limited to 'Lib/inspect.py')
-rw-r--r-- | Lib/inspect.py | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py index e92c355..052f0bf 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -125,6 +125,7 @@ __all__ = [ "ismodule", "isroutine", "istraceback", + "markcoroutinefunction", "signature", "stack", "trace", @@ -391,12 +392,33 @@ def isgeneratorfunction(obj): See help(isfunction) for a list of attributes.""" return _has_code_flag(obj, CO_GENERATOR) +# A marker for markcoroutinefunction and iscoroutinefunction. +_is_coroutine_marker = object() + +def _has_coroutine_mark(f): + while ismethod(f): + f = f.__func__ + f = functools._unwrap_partial(f) + if not (isfunction(f) or _signature_is_functionlike(f)): + return False + return getattr(f, "_is_coroutine_marker", None) is _is_coroutine_marker + +def markcoroutinefunction(func): + """ + Decorator to ensure callable is recognised as a coroutine function. + """ + if hasattr(func, '__func__'): + func = func.__func__ + func._is_coroutine_marker = _is_coroutine_marker + return func + def iscoroutinefunction(obj): """Return true if the object is a coroutine function. - Coroutine functions are defined with "async def" syntax. + Coroutine functions are normally defined with "async def" syntax, but may + be marked via markcoroutinefunction. """ - return _has_code_flag(obj, CO_COROUTINE) + return _has_code_flag(obj, CO_COROUTINE) or _has_coroutine_mark(obj) def isasyncgenfunction(obj): """Return true if the object is an asynchronous generator function. |