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

Type[object] isn't hashable, and can't be asserted to be Hashable #12993

Closed
finite-state-machine opened this issue Jun 17, 2022 · 2 comments
Closed
Labels
bug mypy got something wrong

Comments

@finite-state-machine
Copy link

Bug Report

Context: mypy doesn't regard Type[object] as Hashable. (It is possible with metaclasses that this might be the case, LSP concerns aside.) It rightly complains when Type[object] is used where a Hashable is required.

The issue is that mypy assumes Type[object] cannot be Hashable, even following an assertion, making the above difficult to work around.

To Reproduce

https://mypy-play.net/?mypy=master&python=3.10&gist=3a8ec03c4472430ecbaeaf397dbc0acd

import collections
import functools
import typing
from typing import (
        Type,
        )


@functools.lru_cache(maxsize=None)
def cached_function(type_: Type[object]) -> bool:
    # expensive computation here
    _ = type_
    return True


def function1(type_: Type[object]) -> None:

    # it's theoretically possible for a Type[...] object to be
    # unhashable (although this would seem to violate the Liskov
    # Substitution Principle, LSP)
    assert cached_function(type_)
            # actual, as expected:
            #       error: Argument 1 to "__call__" of
            #       "_lru_cache_wrapper" has incompatible type
            #       "Type[object]"; expected "Hashable" [arg-type]

def function1a(type_: Type[object]) -> None:

    # we attempt to assure mypy that 'type_' is Hashable
    assert isinstance(type_, typing.Hashable)
    reveal_type(type_)
            # expected: revealed type is: ...
            # actual: prints nothing; mypy believes this is unreachable

    assert cached_function(type_)
            # expected: no warning
            # actual: mypy believes this is unreachable

def function1b(type_: Type[object]) -> None:

    # we attempt to assure mypy that 'type_' is Hashable
    assert isinstance(type_, collections.abc.Hashable)
    reveal_type(type_)
            # expected: revealed type is: ...
            # actual: prints nothing; mypy believes this is unreachable

    assert cached_function(type_)
            # expected: no warning
            # actual: mypy believes this is unreachable

Expected Behavior

Adding assert isinstance(..., Hashable) should work around this problem.

Actual Behavior

Asserting that a variable having type Type[object] is Hashable causes mypy to conclude the code is unreachable.

Your Environment

  • Mypy version used: 0.961 and master (on mypy-play.net)
  • Mypy command-line flags: (none required; --warn-unreachable adds insight)
  • Mypy configuration options from mypy.ini (and other config files): (none)
  • Python version used: 3.8, 3.10
  • Operating system and version: macOS 10.14, mypy-play.net
@finite-state-machine finite-state-machine added the bug mypy got something wrong label Jun 17, 2022
@AlexWaygood
Copy link
Member

Duplicate of #11470

@AlexWaygood AlexWaygood marked this as a duplicate of #11470 Jun 17, 2022
@AlexWaygood AlexWaygood closed this as not planned Won't fix, can't repro, duplicate, stale Jun 17, 2022
@finite-state-machine
Copy link
Author

So it is. My apologies!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

2 participants