Skip to content

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

Closed as not planned

Description

@finite-state-machine

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

Activity

  1. AlexWaygood commented on Jun 17, 2022

    @AlexWaygood
    Member

    Duplicate of #11470

  2. finite-state-machine commented on Jun 17, 2022

    @finite-state-machine
    Author

    So it is. My apologies!

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 wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions