Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does mypy not accept a list[str] as a list[Optional[str]]?

Example 1:

from typing import List, Optional

def myfunc() -> List[Optional[str]]:
    some_list = [x for x in "abc"]
    return some_list

Mypy complains on example 1:

Incompatible return value type (got "List[str]", expected "List[Optional[str]]")

However, this example gets no complaint:

Example 2:

def myfunc() -> List[Optional[str]]:
    some_list = [x for x in "abc"]
    return list(some_list)

What is the explanation for the inconsistent behavior?

like image 816
lorg Avatar asked Oct 07 '21 10:10

lorg


People also ask

What is optional str in Python?

As mentioned in the above comments, Optional[str] is a type-hint to be used by IDEs and other static analysis tools, not a default argument. If you want to make a default argument such that you can call the function with a() , then you do need to add = None as you proposed.

How to ignore mypy?

You can add a # type: ignore comment to tell mypy to ignore this error: import frobnicate # type: ignore frobnicate.

Why doesn't mypy type-check all Python packages?

Python packages aren't expected to be type-checked, because mypy types are completely optional. If mypy were to assume every package has type hints, it would show possibly dozens of errors because a package doesn't have proper types, or used type hints for something else, etc.

Why does mypy show different types for different packages?

If mypy were to assume every package has type hints, it would show possibly dozens of errors because a package doesn't have proper types, or used type hints for something else, etc. To opt-in for type checking your package, you need to add an empty py.typedfile into your package's root directory, and also include it as metadata in your setup.py:

Does mypy use strict optional checking?

Starting from mypy 0.600, mypy uses strict optional checking by default, and the None value is not compatible with non-optional types. It’s easy to switch back to the older behavior where None was compatible with arbitrary types (see Disabling strict optional checking ).

Is every class a valid type in mypy?

Every class is also a valid type. Any instance of a subclass is also compatible with all superclasses – it follows that every value is compatible with the object type (and incidentally also the Any type, discussed below). Mypy analyzes the bodies of classes to determine which methods and attributes are available in instances.


Video Answer


1 Answers

Since in Python lists are invariant (see the examples here and here).

If we pass List[str] to someone that expects List[Optional[str]], that someone may add a None to our list and break our assumptions. The second example is valid however as the output of list() in the return statement is not saved anywhere and no one can depend on the the returned value being mutated illegally .

like image 158
lorg Avatar answered Oct 23 '22 04:10

lorg