Проблема проверки типов с io.TextIOBase в Союзе - PullRequest
2 голосов
/ 02 апреля 2020

В следующем коде у меня есть функция, которая может принимать либо строку, либо некоторую TextIOBase. Если строка передается, она интерпретируется как путь к файлу, который необходимо открыть и прочитать. Если передано TextIOBase, содержимое этого потока будет прочитано:

    from typing import Union
    import io

    def function(foo: Union[str, io.TextIOBase]) -> None:
        if isinstance(foo, str):
            foo = open(foo, "w")

    return

Кажется, что все должно быть в порядке, поскольку объединения должны быть ковариантными, что означает, что подкласс одного из типы в объединении должны удовлетворять аннотации типов, и в этом случае тип вывода open() является подклассом TextIOBase. Однако mypy жалуется на:

union.py:6: error: Incompatible types in assignment (expression has type "TextIO", variable has type "Union[str, TextIOBase]")
Found 1 error in 1 file (checked 1 source file)

Я подумал, что, возможно, есть проблема с неоднозначностью типа возвращаемого значения open(), основанного на переданных аргументах, поэтому я попытался вместо этого создать StringIO, но получил ту же ошибку. Какие-нибудь мысли? Почему mypy злится на меня?

Я также пробовал это с некоторыми игрушечными классами (например, Union[str, T1], затем присваивая T2, где T2 является подклассом T1), что mypy идеально доволен.

1 Ответ

2 голосов
/ 02 апреля 2020

Модуль typing имеет для этого выделенный объект: typing.TextIO. Тип возвращаемого значения open определяется на основе аргумента mode и оценивается как один из следующих типов: TextIO, BinaryIO.

...