Bug (?) with Sequence / List #1113
Copy link
Copy link
Closed
Description
This is from the latest master (pip install git+git://github.com/JukkaL/mypy.git).
$ cat file.py
from typing import Dict, Sequence
def f(data: Dict[str, Sequence[int]]) -> None:
pass
data = {"a": [1, 2]}
f(data)
$ mypy file.py
file.py:7: error: Argument 1 to "f" has incompatible type Dict[str, List[int]]; expected Dict[str, Sequence[int]]
If I replace the function call with f({"a": [1, 2]}), instead of defining the dict on a separate line, then it works.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
gvanrossum commentedon Jan 11, 2016
JukkaL commentedon Jan 11, 2016
The behavior is correct, as the second type parameter to
Dictis invariant. However, if you'd useMapping[str, Sequence[int]], this should work (but it doesn't).JukkaL commentedon Jan 11, 2016
To see why mypy complains about the code, consider this slightly different example:
If the value type parameter of
Dictwould be covariant, mypy wouldn't complain about the above example but it would fail with a runtime error -> type checking would be unsound.gvanrossum commentedon Jan 11, 2016
JukkaL commentedon Jan 11, 2016
Mypy treats
Mappingas invariant, but the value type should probably be covariant, at least. The key type could also be covariant.JukkaL commentedon Jan 11, 2016
Another idea: mypy could give a more useful error message when it detects an issue like the original one.
Consider this potential output, for example:
This would give more context even for somebody who doesn't understand covariance/invariance -- these terms are easy to google.
Even better, we could give a pointer to relevant documentation.
gvanrossum commentedon Jan 11, 2016
rmcgibbo commentedon Jan 11, 2016
I would have thought that the two snippets
and
would either both typecheck, or both fail to typecheck, but I'm kind of new at this.
Let me know if you want me to close this issue, since it seems taken care of.
JukkaL commentedon Jan 11, 2016
The latter is different, though the reason is somewhat technical -- as the dictionary is immediately given as an argument to
f, mypy infers a typeDict[str, Sequence[int]]for it. You could achieve the same effect my giving an annotation fordata:If you construct a dictionary as a function argument, the declared argument type effectively acts as an implicit type annotation. However, mypy doesn't look forward when inferring the type of
data, so you have to give an annotation to override the default inferred type.rmcgibbo commentedon Jan 11, 2016
Got it. Thanks, @JukkaL! (The only type system I've really played with is Haskell's -- this one is in most ways much simpler, but I'm just starting to learn the differences.)
gvanrossum commentedon Jan 11, 2016
Robert, can we close this issue (now that we've explained the reason and filed the issues for actual bugs)?