Mypy: Union[]s as dict[] values

Created on 21 Oct 2016  路  1Comment  路  Source: python/mypy

Mypy does not detect the subtype relation (correct term?) when it comes to dict values:

if False:
    from typing import Union

# works
foo1 = 0 # type: int
bar1 = foo1 # type: Union[int, str]

# "Incompatible types in assignment"
foo2 = {} # type: dict[str, int]
bar2 = foo2 # type: dict[str, Union[int, str]]

Mypy 0.4.5

question

Most helpful comment

This is actually correct, because Dict[str, int] is not a subtype of Dict[str, Union[str, int]] (even though int is a subtype of Union[int, str]). The reason is that Dict is defined as _invariant_ in its type parameters, and that is done because Dict is mutable.

Consider this code:

a = {}  # type: Dict[str, int]
def f(b: Dict[str, Union[int, str]]) -> None:
    b['x'] = 'y'
f(a)

If we allowed that call to f(a), a would end up with a string value! To prevent this we don't consider Dict[str, Union[int, str]] a subtype of Dict[str, int].

>All comments

This is actually correct, because Dict[str, int] is not a subtype of Dict[str, Union[str, int]] (even though int is a subtype of Union[int, str]). The reason is that Dict is defined as _invariant_ in its type parameters, and that is done because Dict is mutable.

Consider this code:

a = {}  # type: Dict[str, int]
def f(b: Dict[str, Union[int, str]]) -> None:
    b['x'] = 'y'
f(a)

If we allowed that call to f(a), a would end up with a string value! To prevent this we don't consider Dict[str, Union[int, str]] a subtype of Dict[str, int].

Was this page helpful?
0 / 5 - 0 ratings