Skip to content
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

incompatible type when combining a literal with keyword expansion #12977

Closed
kretes opened this issue Jun 13, 2022 · 0 comments · Fixed by #15174
Closed

incompatible type when combining a literal with keyword expansion #12977

kretes opened this issue Jun 13, 2022 · 0 comments · Fixed by #15174
Labels
bug mypy got something wrong topic-inference When to infer types or require explicit annotations

Comments

@kretes
Copy link

kretes commented Jun 13, 2022

Bug Report
Having a code snippet:

dict1 = {"a": 1, "b": "a"}
dict2 = {"c": 1, "d": 2, **dict1}

I receive
error: Argument 1 to "update" of "MutableMapping" has incompatible type "Dict[str, object]"; expected "SupportsKeysAndGetItem[str, int]" from mypy

To Reproduce
run mypy on the snippet

Expected Behavior
dict1 is Dict[str, object] and hence dict2 should be and mypy shouldn't raise that.

Actual Behavior
I think this gets analyzed sequentially and so first the dict2 type is inferred from the literal entries and gets set to Dict[str, int] which then doesn't accept to call an update using entries from another dict of broader type.

Considering than in Python's syntax this is a single expression - this shouldn't happen like this.

Adding an explicit type to dict2 is a workaround

Your Environment

  • Mypy version used: 0.960
  • Python version used: 3.9.5
@kretes kretes added the bug mypy got something wrong label Jun 13, 2022
@AlexWaygood AlexWaygood added the topic-inference When to infer types or require explicit annotations label Jun 13, 2022
hauntsaninja pushed a commit that referenced this issue May 5, 2023
Fixes #12977

IMO current dict expression inference logic is quite arbitrary: we only
take the non-star items to infer resulting type, then enforce it on the
remaining (star) items. In this PR I simplify the logic to simply put
all expressions as arguments into the same call. This has following
benefits:
* Makes everything more consistent/predictable.
* Fixes one of top upvoted bugs
* Makes dict item indexes correct (previously we reshuffled them causing
wrong indexes for non-star items after star items)
* No more weird wordings like `List item <n>` or `Argument <n> to
"update" of "dict"`
* I also fix the end position of generated expressions to show correct
spans in errors

The only downside is that we will see `Cannot infer type argument` error
instead of `Incompatible type` more often. This is because
`SupportsKeysAndGetItem` (used for star items) is invariant in key type.
I think this is fine however, since:
* This only affects key types, that are mixed much less often than value
types (they are usually just strings), and for latter we use joins.
* I added a dedicated note for this case
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-inference When to infer types or require explicit annotations
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants