Skip to content

Changed strict-equality behavior with dict/Mapping #16340

Closed

Description

@JukkaL

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

Activity

  1. ilevkivskyi commented on Oct 27, 2023

    @ilevkivskyi
    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.

  2. JukkaL commented on Oct 27, 2023

    @JukkaL
    CollaboratorAuthor

    Makes sense! Thanks for looking into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-overlapOverlapping equality check

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions