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?
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.
You can add a # type: ignore comment to tell mypy to ignore this error: import frobnicate # type: ignore frobnicate.
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.
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:
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 ).
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.
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 .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With