-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Fix overlap between TypedDict and Mapping #7164
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
Conversation
|
I checked this out eagerly, as I thought it covers a big use case of @cs-cordero and mine's. But now that I read it closely, it seems related but not the actual solution. That is, this still won't work: from typing import Mapping
from mypy_extensions import TypedDict
def mapping_test(thing: Mapping[str, str]) -> bool:
return True
class Foo(TypedDict):
foo: str
a = Foo(foo="a")
b: Foo = {'foo': 'a'}
mapping_test(a) # Errors out still, with below.
mapping_test(b) # Errors out still, with below.
# Argument 1 to "mapping_test" has incompatible type "Foo"; expected "Mapping[str, str]"You mention "overlap" but in this case, it's referring strictly to equality and overloads, not general types matching. Is that right? Is our use case a big stretch? Either way, thanks for all the work on mypy! |
|
Adding a more thorough snippet that demonstrates what works and what doesn't as of this PR, in case it's helpful. All running with from typing import Mapping
from mypy_extensions import TypedDict
def mapping_test(thing: Mapping[str, str]) -> bool:
return True
class Foo(TypedDict):
foo: str
a = Foo(foo="a")
b: Foo = {"foo": "a"}
c: Mapping[str, str] = {"foo": "a"}
a == b == c # Works
mapping_test(c) # Works, of course
mapping_test(a) # Does not work
mapping_test(b) # Does not work |
Michael0x2a
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had one minor suggestion, but otherwise lgtm!
| only if at least one of key types overlaps with <some type>. For example: | ||
|
|
||
| - TypedDict(x=str, y=str, total=False) overlaps with Dict[str, str] | ||
| - TypedDict(x=str, y=str, total=False) doesn't overlap with Dict[str, int] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a third example could be - TypedDict(x=int, y=str, total=False) overlaps with Dict[str, str]`?
|
@silviogutierrez Your issue is completely unrelated. The code is your example is unsafe because typed dicts use structural subtyping, you can use |
Fixes #7036
This adds more "fine grained" logic for overlap between
TypedDictandMappingused by overload checks and--strict-equality. Basically the rules are:TypedDictwith some required keys is overlapping withMapping[str, <some type>]if and only if every key type is overlapping with<some type>.TypedDictwith no required keys overlaps withMapping[str, <some type>]if and only if at least one of key types overlaps with<some type>.TypedDictwith no required keys doesn't overlap withMapping[str, <some type>]), but is itself (i.e.Mapping[<nothing>, <nothing>]) overlapping with aTypedDictwith no required keys.