Определить любую функцию, созданную с помощью async def - PullRequest
2 голосов
/ 10 июля 2019

Я озадачен следующим поведением в Python 3.6 +:

>>> def f1(): pass
>>> def f2(): yield
>>> async def f3(): pass
>>> async def f4(): yield
>>> inspect.isfunction(f1)
True
>>> inspect.isfunction(f2)
True
>>> inspect.iscoroutinefunction(f3)
True
>>> inspect.iscoroutinefunction(f4)
False

Как синхронные функции, так и функции генератора при проверке считаются "функциями", но асинхронные функции генератора не считаются "функциями сопрограммы". Это кажется противоречащим документации

inspect.iscoroutinefunction(object)

Возвращает true, если объект является функцией сопрограммы (функция, определенная с синтаксисом async def).

Есть ли лучший способ определить, была ли определена функция с помощью async, включая функции генератора, чем проверка iscoroutinefunction и isasyncgenfunction?

Это может быть связано с тем, что асинхронные генераторы появились только в версии 3.6, но все еще озадачивают.

1 Ответ

1 голос
/ 10 июля 2019

Асинхронные генераторы сами по себе не являются сопрограммами и не могут быть await ed:

>>> loop.run_until_complete(f4())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/haugh/.pyenv/versions/3.6.6/lib/python3.6/asyncio/base_events.py", line 447, in run_until_complete
    future = tasks.ensure_future(future, loop=self)
  File "/home/haugh/.pyenv/versions/3.6.6/lib/python3.6/asyncio/tasks.py", line 526, in ensure_future
    raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required

Я думаю, что вы уже определили лучший способ проверки, использовался ли async для определения функции:

def async_used(func):
    return inspect.iscoroutinefunction(func) or inspect.isasyncgenfunction(func)
...