Title: inspect.iscoroutinefunction / isgeneratorfunction / isasyncgenfunction can't handle partialmethod objects
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.8
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: asvetlov, dreamsorcerer, mjpieters, yselivanov
Priority: normal Keywords: patch

Created on 2019-10-03 13:28 by mjpieters, last changed 2020-06-07 12:59 by dreamsorcerer.

Pull Requests
URL Status Linked Edit
PR 16600 open mjpieters, 2019-10-05 22:51
Messages (1)
msg353849 - (view) Author: Martijn Pieters (mjpieters) * Date: 2019-10-03 13:28
This is a follow-up to #33261, which added general support for detecting generator / coroutine / async generator functions wrapped in partials. It appears that partialmethod objects were missed out.

While a partialmethod object will produce a functools.partial() object on binding to an instance, the .func attribute of that partial is a bound method, not a function, and the current _has_code_flag implementation unwraps methods *before* it unwraps partials.

Next, binding to a class produces a partialmethod._make_unbound_method.<locals>._method wrapper function. _unwrap_partial can't unwrap this, as it doesn't handle this case; it could look for the `_partialmethod` attribute and follow that to find the `.func` attribute.

Test case:

import inspect
import functools

class Foo:
    async def bar(self, a): return a
    ham = partialmethod(bar, "spam")

print(inspect.iscoroutinefunction(  # True
print(inspect.iscoroutinefunction(Foo.ham)  # False
instance = Foo()
print(inspect.iscoroutinefunction(  # True
print(inspect.iscoroutinefunction(instance.ham)  # False
Date User Action Args
2020-06-07 12:59:45dreamsorcerersetnosy: + dreamsorcerer
2019-10-05 22:51:55mjpieterssetkeywords: + patch
stage: patch review
pull_requests: + pull_request16188
2019-10-03 13:38:56xtreaksetnosy: + asvetlov, yselivanov
2019-10-03 13:28:44mjpieterscreate