python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.48k stars 2.83k forks source link

Incompatible types in assignment for `dict[key] = tmp = value` and nested structures #5289

Open pmhahn opened 6 years ago

pmhahn commented 6 years ago

I have Python2 code building some nested structures like lists/tuples/sets/dicts in dicts. For populating the nested structure I keep a temporary reference, which mypy fails to parse if the (untyped) temporary reference is not the first variable being assigned:

#!/usr/bin/python2.7
from typing import Dict, Set  # noqa
x = {}  # type: Dict[str, Set[str]]
z = x[''] = set()  # okay
x[''] = y = set()  # fail: Incompatible types in assignment (expression has type "Set[<nothing>]", target has type "Set[str]")
ilevkivskyi commented 6 years ago

Hm, interesting, mypy processes the targets in a weird order, first lvalues[-1], then lvalues[:-1]. It infers the rvalue type only once, then uses it for subsequent targets. This logic is apparently broken when the first inference fails. Since y is a new variable and the set is empty, mypy can't infer the type correctly as in first case. A possible solution is to check if the previous inference failed (look for partial types and uninhabited types with ambiguous=True), and in this case attempt the next lvalue.

This however might need some refactoring, so I think this is relatively low priority, also there are workarounds: declare types of problematic variables upfront, instead of relying on inference, or use a single assignment target, or change their order.