Fix mypy error

I check my code with the mypy analyzer. The following errors occurred:

  1. There is an object names: List[str], an error {[18] is returned for the expressionlen(names)]}

    Argument 1 to "len" has incompatible type "Optional[List[str]]"; expected "Sized"

    When indexing names[i], the following error is returned:

    Value of type "Optional[List[str]]" is not indexable

  2. There is an object matrix: List[List[int]], similar to indexing matrix[i][j]

    Value of type "Optional[List[List[int]]]" is not indexable

  3. There is an object

     def func() -> Dict[str, List[str]]
         g = {"1": ["2"],
             "2": ["3"]}
         return g
    

    Described as Dict[str, List[str]], an error is thrown:

    Incompatible return value type (got "Dict[str, object]", expected "Dict[str, List[str]]") Unclear, why did you get this type? If you change it to Dict[str, object], errors appear further down the code.

  4. When accessing the object from point 3:

     d: DefaultDict[str, List[str]] = defaultdict(list)
     for obj in g:
         d[obj].extend(g.get(obj))
    

    The following error occurs:

    Argument 1 to "extend" of "list" has incompatible type "Optional[List[str]]"; expected "Iterable[str]"

I'm new to python and don't really understand the principles of working correctly with mypy - how do I correctly write type annotations so as not to get such errors?

Author: insolor, 2020-09-10

1 answers

1 and 2:

Optional says that you can have a value not only of the type specified via the annotation, but also None - for example, if None is set in the default parameter value for the function. Then, without checking the value for None, you try to work with these values as with lists. You need to add a check for None, then there will be no errors.

Example:

# Неправильно:
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:

You forgot the colon at the end of the line def, and so mypy errors do not occur issues:

def func() -> Dict[str, List[str]]:  # <-- добавил двоеточие
    g = {"1": ["2"],
        "2": ["3"]}
    return g

4:

The get dictionary method can return None if there is no key in the dictionary (i.e. it has the return value type Optional[тип значения из словаря]). Since the keys are taken from the same dictionary, the situation when None returns is virtually impossible, but mypy is not smart enough to understand this. You just need to replace getting the value through get with getting it through square brackets, then the error will disappear:

g = func()
d: DefaultDict[str, List[str]] = defaultdict(list)
for obj in g:
    d[obj].extend(g[obj])  # было g.get(obj), стало g[obj]
 4
Author: insolor, 2020-09-11 08:43:17