IDE указывает на ошибку в аннотации типов, но код работает правильно

Есть правильно работающий кусок кода, который эквивалентен такому:

from typing import Optional


class Game:
    pass


def select(game: Game) -> Optional[Game]:
    vs: list[Game] = []
    next_games: list[list[Game, int]] = [[v, 0] for v in vs]

    if not next_games:
        return None

    next_games[0][1] = 0 # Тут

    return next_games[0][0]

PyCharm ругается на помеченную строчку, выдавая ошибку

Unexpected type(s):(int, int)Possible types:(int, Game)(slice, Iterable[Game])

Подскажите, что она означает и как ее исправить.


Ответы (1 шт):

Автор решения: Rennorb

Во-первых, я нашел у себя ошибку: изначально вторая строчка метода select выглядела так (и ошибок не было):

next_games: list[tuple[Game, int]] = [[v, 0] for v in vs]

а потом я добавил помеченную строчку и поменял tuple на list. Что именно означает тип list[Game, int] я пока не понял, но подозреваю, что такая запись равносильна list[Game]. Правильно было бы написать

next_games: list[list[Union[Game, int]]] = [[v, 0] for v in vs]

Во-вторых, я, кажется, понял, как расшифровать само сообщение об ошибке. Для этого рассмотрим несколько примеров:

  1. Заменим помеченную строчку на next_games[0] = None, тогда ошибка превратится в Unexpected type(s):(int, None)Possible types:(int, list[Game, int])(slice, Iterable[list[Game, int]]).

  2. Заменим помеченную строчку на next_games[0][vs[0]] = None, тогда ошибка превратится в Unexpected type(s):(Game, None)Possible types:(int, Game)(slice, Iterable[Game]).

Интерпретирую это так: кортеж содержит в себе тип объекта в последних квадратных скобках и то, что стоит справа от знака равно.

→ Ссылка