Исправить ошибку mypy
Проверяю свой код анализатором mypy. Возникли следующие ошибки:
Имеется объект
names: List[str], на выражениеlen(names)выдается ошибкаArgument 1 to "len" has incompatible type "Optional[List[str]]"; expected "Sized"При индексации
names[i]выдается следующая ошибка:Value of type "Optional[List[str]]" is not indexableИмеется объект
matrix: List[List[int]], аналогично при индексацииmatrix[i][j]Value of type "Optional[List[List[int]]]" is not indexableИмеется объект
def func() -> Dict[str, List[str]] g = {"1": ["2"], "2": ["3"]} return gописанный как
Dict[str, List[str]], вылетает ошибка:Incompatible return value type (got "Dict[str, object]", expected "Dict[str, List[str]]")Неясно, почему получился такой тип. Если изменить его наDict[str, object], дальше по коду появляются ошибки.При обращении к объекту из п. 3:
d: DefaultDict[str, List[str]] = defaultdict(list) for obj in g: d[obj].extend(g.get(obj))Вылетает следующая ошибка:
Argument 1 to "extend" of "list" has incompatible type "Optional[List[str]]"; expected "Iterable[str]"
Я новичок в python и не очень понимаю принципы корректной работы с mypy - как мне грамотно писать аннотации к типам, чтобы не получать таких ошибок?
Ответы (1 шт):
1 и 2:
Optional говорит о том, что у вас значение может быть не только заданного через аннотацию типа, но и None - например, если None задано в значении параметра по-умолчанию для функции. Дальше вы не проверяя значение на None пытаетесь с этими значениями работать как со списками. Нужно добавить проверку на None, тогда ошибок не будет.
Пример:
# Неправильно:
def test(names: List[str]=None, matrix: List[List[int]]=None):
print(names[0]) # Ошибка: Value of type "Optional[List[str]]" is not indexable
print(len(names)) # Ошибка: Argument 1 to "len" has incompatible type "Optional[List[str]]"; expected "Sized"
print(matrix[0][0]) # Ошибка: Value of type "Optional[List[List[int]]]" is not indexable
# Правильно:
def test(names: List[str]=None, matrix: List[List[int]]=None):
if names is not None:
print(names[0])
print(len(names))
if matrix is not None:
print(matrix[0][0])
3:
Вы забыли двоеточие в конце строки def, а так mypy ошибок не выдает:
def func() -> Dict[str, List[str]]: # <-- добавил двоеточие
g = {"1": ["2"],
"2": ["3"]}
return g
4:
Метод get словаря может возвращать None, если ключа в словаре нет (т.е. у него тип возвращаемого значения Optional[тип значения из словаря]). Т.к. ключи берутся из этого же словаря, то ситуация, когда вернется None, фактически невозможна, но mypy не настолько умный, чтобы это понимать. Нужно просто заменить получение значения через get на получение через квадратные скобки, тогда ошибка пропадет:
g = func()
d: DefaultDict[str, List[str]] = defaultdict(list)
for obj in g:
d[obj].extend(g[obj]) # было g.get(obj), стало g[obj]