В следующем коде у меня есть функция, которая может принимать либо строку, либо некоторую 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 идеально доволен.