Как сообщить PyCharm, что асинхронный прибор что-то возвращает

#python #async-await #pycharm #pytest

#python #асинхронное ожидание #pycharm #pytest

Вопрос:

Пример:

 import pytest


@pytest.fixture
async def phrase():
    return 'hello world'


@pytest.fixture
async def replaced(phrase):
    return phrase.replace('hello', 'goodbye')
 

Метод .replace окрашен в желтый цвет, и в предупреждении говорится:

 Unresolved attribute reference 'replace' for class 'Coroutine'
 

Однако эти устройства работают. Если я удаляю async из def phrase(): Pycharm, он обрабатывается .replace правильно, показывая, что это метод класса str . Есть ли какой-либо способ сообщить PyCharm, что phrase при использовании in replaced будет экземпляром str , а не a Coroutine ? Желательно, без повторения кода для каждого прибора, который будет использоваться phrase .

Комментарии:

1. Просто дикое предположение: работает ли подсказка типа с : str работой?

2. К сожалению, нет.

3. yield 'hello world' вместо return ввода.

4. @hoefling это работает! Подумайте о написании ответа? Может быть, вы знаете, почему yield работает, но return не работает?

Ответ №1:

Это не ваш код, это проблема Pycharm — он неправильно разрешает возвращаемые типы встроенных приспособлений сопрограммы. Pycharm разрешит старый инструмент сопрограммы на основе генератора

 @pytest.fixture
async def phrase():
    yield 'hello world'
 

в качестве Generator[str, Any, None] и сопоставьте аргумент с типом возвращаемого устройства. Однако встроенное приспособление сопрограммы

 @pytest.fixture
async def phrase():
    return 'hello world'
 

является a Coroutine[Any, Any, str] и в настоящее время Pycharm не сопоставляет тестовые аргументы со своим типом возвращаемого значения (протестировано с Pycharm CE 2019.1). Таким образом, у вас есть две возможности:

Установите явные подсказки типа

Поскольку вы знаете, что должны возвращать сопрограммы, задайте типы return и arg, и Pycharm перестанет угадывать. Это самый простой и надежный подход:

 @pytest.fixture
async def phrase() -> str:
    return 'hello world'


@pytest.fixture
async def replaced(phrase: str) -> str:
    return phrase.replace('hello', 'goodbye')
 

Переключитесь на сопрограммные приспособления на основе генератора

Это означало yield бы редактирование вместо return редактирования, как я предложил в комментариях; однако вам решать, следует ли вам изменять явно правильный код, чтобы обойти проблему Pycharm.

Комментарии:

1. Явные подсказки типа (оба -> str и : str ) не помогают PyCharm понять, что phrase это str . 🙁

2. Какую версию Pycharm вы используете? Установка явных подсказок типа работает с Pycharm CE 2019.1, хотя не уверен в более старых версиях.

3. Профессиональный 2018.3

4. Я проверю проблему с помощью 2018.3 Pro завтра на компьютере коллеги; однако важной подсказкой типа должен быть test arg ( replaced(phrase: str) ) . Типы возвращаемых приспособлений действительно незначительны; Я вставил их для полноты картины.