Как я могу заставить Pycharm распознавать возвращаемый подкласс X? - PullRequest
0 голосов
/ 21 апреля 2019

При наличии метода, который может возвращать несколько вещей, как я могу предложить pycharm предлагать точные параметры intellisense, основанные на фактическом возвращенном значении?

Expected type 'Union[str, Type[PyPage]]', got 'ExamplePageObject' instead

ExamplePageObject extends PyPage

 _basic_page = ExamplePageObject()
    def test_simple_page_object_launching(self):
        assert start(self._basic_page).retrieve_the_text() == "Hello World"

звонки:

def start(entry_point: Union[str, Type[PyPage]]) -> Union[PyleniumDriver, Type[PyPage]]:
    return PyleniumDriver().maximize().goto(entry_point)

звонки:

    def goto(self, entry_point: Union[str, Type[PyPage]]) -> Union[PyleniumDriver, Type[PyPage]]:
        url = (
            PyleniumConfig().base_url + entry_point
            if isinstance(entry_point, str)
            else entry_point.url
        )
        if not url:
            raise PyPageException(
                "The url was empty, did your page object specify the self.url parameter?"
            )
        else:
            self.driver.get(url)
            if isinstance(entry_point, PyPage):
                return entry_point
        return self

В зависимости от того, что было предоставлено start (), он должен возвращать экземпляр этой страницы и Pycharmдолжно ли быть «осведомлено» о методах, которыми обладает эта страница, возможно ли это?

1 Ответ

0 голосов
/ 26 апреля 2019

Вероятно, вы можете получить что-то, что в основном работает, комбинируя вместе generics и перегрузки .

(Примечание: это ссылки на документы mypy, но описанное поведение должнобыть более или менее одинаковым поведением PyCharm. Mypy и PyCharm в основном уважают семантику хинтинга типа PEP 484.)

Например, что-то вроде этого:

from typing import overload, Union, Type, TypeVar

_T = TypeVar('_T', bound=PyPage)

@overload
def start(entry_point: str) -> PyleniumDriver: ...

@overload
def start(entry_point: Type[_T]) -> Type[_T]: ...

def start(entry_point: Union[str, Type[_T]]) -> Union[PyleniumDriver, Type[_T]]:
    return PyleniumDriver().maximize().goto(entry_point)

Перегрузки позволяют вамобеспечить что-то вроде ограниченного сопоставления с образцом - средство проверки типов проанализирует ваши входные аргументы, выяснит, какая из определенных перегрузок лучше всего подходит, и выберет соответствующее возвращаемое значение.

TypeVar позволяет нам создавать универсальная функция - короче говоря, когда средство проверки типов определит, какой тип _T должен быть в одном месте, оно будет использовать этот же тип во всех других местах, где появляется _T.

Я рекомендую прочитать две ссылки выше, прежде чем пытаться использовать любую из этих функций.Мое объяснение того, что происходит, едва адекватно.

...