7

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?

1 Answer 1

6

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 .

Sign up to request clarification or add additional context in comments.

3 Comments

list invariance is sure part of the story, but i'd also expect python to be able to infer the types here regardless. I consider it a bug that mypy's too eager in inferring the type of some_list as list[str]
@joel I'd consider that a feature request, and it's not obvious what the behaviour should be. There would be similar examples to this code where you want List[str] for the intermediate variable.
@kaya3 yes you're right it is a feature request. I went as far as calling it a bug because I feel it's so important to user experience

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.