Несмотря на то, что одним из значений словаря является int, mypy не может этого сделать.
Mypy это правильно. В вашем коде есть ошибка, и mypy правильно ее помечает. В вашем коде нет гарантии, что data['start']
и data['end']
всегда будут целыми числами.
Ваша подпись data
Dict[str, Union[str, int]]
, поэтому значения имеют тип Union[str, int]
. Mypy должен предполагать, что всегда правильно передать {'start': '2018-07-12', 'end': -42}
, поэтому возвращаемое значение должно быть Tuple[Union[str, int], Union[str, int]]
. Ваше утверждение о том, что функция возвращает Tuple[int, int]
, противоречит this.
Неважно, что на самом деле происходит во время выполнения. Не в этом дело; mypy - это статическая проверка типов, предназначенная для защиты от ошибок в вашем поведении во время выполнения. Здесь важно то, что в соответствии с подсказками типа возможно передать нецелочисленные значения для start
и end
, поэтому проверка типов не может защитить вас от будущих ошибок в вашем коде, которые случайно установить строковое значение для любого из этих двух ключей.
Если вы передаете структурированные данные в словарях, вам всегда придется бороться с mypy по этому поводу, поскольку словари действительно являются неправильной структурой для этого. Вы действительно хотите использовать именованный кортеж или класс данных здесь.
Я использую здесь имя FooBar
, но я уверен, что для вашего конкретного приложения будет лучшее имя для структуры данных, которую вы передаете:
from typing import NamedTuple
class FooBar(NamedTuple):
start: int
end: int
# other fields, perhaps with defaults and Optionals
def select_range(data: FooBar) -> Tuple[int, int]:
if data.start and data.end:
return data.start, data.end
return 1, 1
person
Martijn Pieters
schedule
12.07.2018
mypy
правильно. У вас есть значения dict какUnion[str, int]
, но тип возвращаемого значения в подписи какint
. Измените тип возвращаемого значения или не указывайте тип значений вdata
. - person Jared Smith   schedule 12.07.2018