Как сказать PyCharm, что асинхронное устройство возвращает что-то - PullRequest
4 голосов
/ 17 апреля 2019

Пример:

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 при использовании в replaced будет экземпляром str, а не Coroutine? Предпочтительно, без повторения кода для каждого прибора, который будет использовать phrase.

1 Ответ

1 голос
/ 17 апреля 2019

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

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

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

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

- это 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.

...