diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2018-10-26 11:19:14 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-26 11:19:14 (GMT) |
commit | 7cd25434164882c2093ea41ccfc7b95a05cd5cbd (patch) | |
tree | 76c33543b495e78b0e520dd4914da68dcf616dae /Lib/inspect.py | |
parent | e483f02423917dc4dfd25f46e5b9e6fce304777d (diff) | |
download | cpython-7cd25434164882c2093ea41ccfc7b95a05cd5cbd.zip cpython-7cd25434164882c2093ea41ccfc7b95a05cd5cbd.tar.gz cpython-7cd25434164882c2093ea41ccfc7b95a05cd5cbd.tar.bz2 |
bpo-34890: Make iscoroutinefunction, isgeneratorfunction and isasyncgenfunction work with functools.partial (GH-9903)
inspect.isfunction() processes both inspect.isfunction(func) and
inspect.isfunction(partial(func, arg)) correctly but some other functions in the
inspect module (iscoroutinefunction, isgeneratorfunction and isasyncgenfunction)
lack this functionality. This commits adds a new check in the mentioned functions
in the inspect module so they can work correctly with arbitrarily nested partial
functions.
Diffstat (limited to 'Lib/inspect.py')
-rw-r--r-- | Lib/inspect.py | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py index 3edf97d..b8a1422 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -168,30 +168,33 @@ def isfunction(object): __kwdefaults__ dict of keyword only parameters with defaults""" return isinstance(object, types.FunctionType) -def isgeneratorfunction(object): +def isgeneratorfunction(obj): """Return true if the object is a user-defined generator function. Generator function objects provide the same attributes as functions. See help(isfunction) for a list of attributes.""" - return bool((isfunction(object) or ismethod(object)) and - object.__code__.co_flags & CO_GENERATOR) + obj = functools._unwrap_partial(obj) + return bool((isfunction(obj) or ismethod(obj)) and + obj.__code__.co_flags & CO_GENERATOR) -def iscoroutinefunction(object): +def iscoroutinefunction(obj): """Return true if the object is a coroutine function. Coroutine functions are defined with "async def" syntax. """ - return bool((isfunction(object) or ismethod(object)) and - object.__code__.co_flags & CO_COROUTINE) + obj = functools._unwrap_partial(obj) + return bool(((isfunction(obj) or ismethod(obj)) and + obj.__code__.co_flags & CO_COROUTINE)) -def isasyncgenfunction(object): +def isasyncgenfunction(obj): """Return true if the object is an asynchronous generator function. Asynchronous generator functions are defined with "async def" syntax and have "yield" expressions in their body. """ - return bool((isfunction(object) or ismethod(object)) and - object.__code__.co_flags & CO_ASYNC_GENERATOR) + obj = functools._unwrap_partial(obj) + return bool((isfunction(obj) or ismethod(obj)) and + obj.__code__.co_flags & CO_ASYNC_GENERATOR) def isasyncgen(object): """Return true if the object is an asynchronous generator.""" |