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

Wrong "Non-overlapping equality check" warning #12561

Open
rggjan opened this issue Apr 11, 2022 · 3 comments
Open

Wrong "Non-overlapping equality check" warning #12561

rggjan opened this issue Apr 11, 2022 · 3 comments
Labels
bug mypy got something wrong topic-calls Function calls, *args, **kwargs, defaults topic-overlap Overlapping equality check

Comments

@rggjan
Copy link

rggjan commented Apr 11, 2022

Running this code:

from typing import Any, Callable


class Foo:
    def __init__(self, a: int) -> None:
        print(a)


def bar(f: Callable[[Any], Any]) -> None:
    if type(f) ==Foo:
        print("The same!")

    f(3)


bar(Foo)

with mypy 0.942 and "strict_equality" enabled leads to:

error: Non-overlapping equality check (left operand type: "Type[Callable[[Any], Any]]", right operand type: "Type[Foo]")

I think this is wrong, as clearly, mypy accepts Foo as a correct argument to bar, in which case checking if f inside the function is of type Foo should also be valid...

@rggjan rggjan added the bug mypy got something wrong label Apr 11, 2022
@AlexWaygood AlexWaygood added the topic-overlap Overlapping equality check label Apr 11, 2022
@Akuli
Copy link
Contributor

Akuli commented Apr 11, 2022

f is not of type Foo in your example though. It's literally the class Foo, not an instance of Foo, so type(f) will be the metaclass of Foo, which is confusingly type.

For the equality check to be true, you would have to create a subclass of Foo with __call__ in it, so that you would have a callable instance of Foo.

@AlexWaygood
Copy link
Member

AlexWaygood commented Apr 11, 2022

You do still get an erroneous non-overlapping equality check for this code though, which is more correct:

from typing import Any, Callable


class Foo:
    def __init__(self, a: int) -> None:
        print(a)


def bar(f: Callable[[Any], Any]) -> None:
    if f == Foo:  # error: Non-overlapping equality check (left operand type: "Callable[[Any], Any]", right operand type: "Type[Foo]"
        print("The same!")

    f(3)


bar(Foo)

@AlexWaygood AlexWaygood added the topic-calls Function calls, *args, **kwargs, defaults label Apr 11, 2022
@rggjan
Copy link
Author

rggjan commented Apr 11, 2022

Oh, you're both right of course! Yes, I actually did have a typo in my sample code. I meant to have the check like: type(f) == type(Foo), which is very similar to your (@AlexWaygood) f == Foo conceptually.

It results in an error as well:

error: Non-overlapping equality check (left operand type: "Type[Callable[[Any], Any]]", right operand type: "Type[Type[Foo]]")

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-calls Function calls, *args, **kwargs, defaults topic-overlap Overlapping equality check
Projects
None yet
Development

No branches or pull requests

3 participants