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

Changed strict-equality behavior with dict/Mapping #16340

Closed
JukkaL opened this issue Oct 27, 2023 · 2 comments
Closed

Changed strict-equality behavior with dict/Mapping #16340

JukkaL opened this issue Oct 27, 2023 · 2 comments
Labels
bug mypy got something wrong topic-overlap Overlapping equality check

Comments

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 27, 2023

When using mypy 1.6, this example produces no errors:

# mypy: strict-equality

from typing import Mapping

def f(x: dict[str, int | None], y: dict[str, str | None]) -> bool:
    return x == y

def g(x: Mapping[str, int], y: str) -> bool:
    return x == y

However, after #16237, it started generating these errors:

t.py:6: error: Non-overlapping equality check (left operand type: "dict[str, int | None]", right operand type: "dict[str, str | None]")  [comparison-overlap]
t.py:9: error: Non-overlapping equality check (left operand type: "Mapping[str, int]", right operand type: "str")  [comparison-overlap]

I'm not sure if the new behavior is better or not, but I suspect that the change in behavior may have been an unintended consequence of #16237, so it seems worth investigating what is going on.

cc @ilevkivskyi

@JukkaL JukkaL added the bug mypy got something wrong label Oct 27, 2023
@AlexWaygood AlexWaygood added the topic-overlap Overlapping equality check label Oct 27, 2023
@JukkaL JukkaL mentioned this issue Oct 27, 2023
2 tasks
@ilevkivskyi
Copy link
Member

This is actually intentional. For my len() PR I needed to disable the len() check if a tuple subclass has a custom (i.e. user-defined) __len__() (and/or a user-defined __bool__() for cases like assert some_tuple). But then it turned out the existing helper custom_special_method() didn't work, because it considered special methods defined in typing as user-defined (it only allowed builtins as not user-defined), and tuple gets its __len__() from typing. But also it turns out dict gets its __eq__() from typing as well, so we actually never checked unsafe overlap for dictionaries/mappings (because we always considered equality as user-defined there).

FWIW I think the new behavior is consistent with how we handle e.g. lists etc where we get

Non-overlapping equality check (left operand type: "list[int | None]", right operand type: "list[str | None]")

I propose closing this.

@JukkaL
Copy link
Collaborator Author

JukkaL commented Oct 27, 2023

Makes sense! Thanks for looking into this.

@JukkaL JukkaL closed this as completed Oct 27, 2023
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-overlap Overlapping equality check
Projects
None yet
Development

No branches or pull requests

3 participants