-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Incorrect type inferred for **dict(iterable) #1360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Perhaps also interesting: if I comment out the call callee = self.infer_function_type_arguments_using_context(
callee, context) from check_call() in mypy/checkexpr.py, I get a different error message:
What's so interesting about this is that I get exactly the same error (still with that infer_ call commented out) if I remove the f2(dict(iterable)) That suggests to me that the original problem is really caused by incorrectly taking the type of the first argument to f2(), which also happens to be |
Hm... Looks like either |
I think |
Here's a simpler example showing that at least part of the problem seems to be the message formatting:
All three lines with errors give the same error message, even though the reasons are actually different:
But even if we were to fix this, we'd still have the problem that in a call like |
I strongly believe the correct fix for the incorrect inference context is to add |
…hether * or ** was involved. This fixes the issue reported in #1360 (comment) . Specifically, suppose you have these three calls (regardless of how f() is defined!) ``` f(a) f(*a) f(**a) ``` If the type checker determines that there's something wrong with the argument type it always gives the same error message. That error message is appropriate for the first example, `f(a)`, but for the second and third it should at least indicate that the mismatch is due to the star(s) in the call site. I am addressing this by adding one or two stars (as appropriate) in front of the actual type in the error message, so that e.g. instead of ``` Argument 1 to "f" has incompatible type Dict[str, int]; expected "str" ``` you would see ``` Argument 1 to "f" has incompatible type **Dict[str, int]; expected "str" ``` Hopefully this will inform the user that (1) the type of a in `f(**a)` is `Dict[str, int]` and (2) the actual type that doesn't match the expected type "str" is the value slot, in this case `int`. Similar for `*args`.
This was reported by @ahaven on our internal Slack; @ddfisher came up with the following minimal repro.
We get the following mysterious error:
Some debugging shows that
Iterable[...]
in the error message stands forIterable[Tuple[Tuple[str, int], <something>]
, IOW it somehow takesDict[KT, VT]
and substitutes theTuple[str, int]
for just KT, even though the variant it chose from the overloaded dict constructor hasiterable: Iterable[Tuple[KT, VT]]
as its lone arg.I think I've followed the trail into infer_type_arguments() at the very end of mypy/infer.py; it gets called with:
After calling
infer_constraints(template, actual, SUBTYPE_OF)
, constraints is set towhich seems to tell me that type var -1 (i.e.
_KT
) is both a subtype and a supertype ofTuple[str, int]
while leaving type var -2 (i.e._VT
) unconstrained. The reported error follows from this I think.I can also understand why these constraints are inferred -- it tries to match
Dict[KT, VT]
withIterable[Tuple[...]]
and of courseDict[KT, VT]
inherits fromIterable[KT]
so the tuple type ends up associated with KT -- but it appears confused because we should actually take the argument rather than the return type.That's all I have for now.
The text was updated successfully, but these errors were encountered: