mypy
mypy copied to clipboard
Typing information lost while calling __iter__
With the following example:
from typing import Literal
dest: Literal["tata", "tutu"]
for src in "tata", "tutu":
dest = src
I'm getting:
error: Incompatible types in assignment (expression has type "str", variable has type "Literal['http', 'https']")
Trying to dig with reveal_type
:
t = "tata", "tutu"
reveal_type(t)
reveal_type(t.__iter__())
I get:
test.py:2: note: Revealed type is "Tuple[builtins.str, builtins.str]"
test.py:3: note: Revealed type is "typing.Iterator[builtins.str*]"
So it looks OK, but digging with pdb, in mypy/checker.py:analyze_iterable_item_type()
, after calling:
iterator = echk.check_method_call_by_name('__iter__', iterable, [], [], expr)[0]
I see:
iterable == Tuple[Literal['foo']?, Literal['bar']?]
iterator == typing.Iterator[builtins.str*])
I think some information is lost here, should iterator get: typing.Iterator[Literal['foo', 'bar']]
instead?
Hum I played with join_instances
so joining two Literal of strings give an union of the two string literals to avoid loosing information, instead of returning str
.
But later during the assignement of the for loop variable, in checker.py
, in check_assignment()
, even if the value from the right is precise (like Union[Literal['tutu']?, Literal['tata']?]
, the info get lost at:
rvalue_type = remove_instance_last_known_values(rvalue_type)
which falls back again to:
Union[builtins.str, builtins.str]
So no luck, instead of getting:
error: Incompatible types in assignment (expression has type "str", variable has type "Union[Literal['tata'], Literal['tutu']]")
I'm getting:
error: Incompatible types in assignment (expression has type "Union[str, str]", variable has type "Union[Literal['tata'], Literal['tutu']]")
(I'm not sure I'm following the right path...)
I'm having the same issue. My code looks like:
from typing import Literal
dest: Literal["tata", "tutu"]
for src in ["tata", "tutu"]:
dest = src
and mypy is complaining