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

x has incompatible type "int"; expected "Hashable" #2412

Closed
sametmax opened this issue Nov 7, 2016 · 4 comments
Closed

x has incompatible type "int"; expected "Hashable" #2412

sametmax opened this issue Nov 7, 2016 · 4 comments

Comments

@sametmax
Copy link

sametmax commented Nov 7, 2016

I used collections.Hashable as a type for something expected to be a dictionary key. Passing an integer gives me the error x has incompatible type "int"; expected "Hashable", despite the fact that isinstance(1, Hashable) == True.

@gvanrossum
Copy link
Member

This is a complex issue. I suppose we could try to "solve" it in typeshed by making int, and float, and str, and lots of other types, inherit from Hashable -- but that's not really enough, given this comment in the definition of Hashable in stdlib/3/typing.pyi there:

class Hashable(metaclass=ABCMeta):
    # TODO: This is special, in that a subclass of a hashable class may not be hashable
    #   (for example, list vs. object). It's not obvious how to represent this. This class
    #   is currently mostly useless for static checking.
    @abstractmethod
    def __hash__(self) -> int: ...

Note that even in Python itself Hashable is special -- it overrides isinstance() to dynamically check for __hash__ existing and not being defined as None. I suppose we could arrange for mypy to special-case isinstance(x, Hashable) and doing a similar check on the type of x, but that's an expensive one-off where we really would like to focus on supporting structural type checking for all types: python/typing#11

Do you have a work-around? I can't think of a really good one apart from # type: ignore or aliasing Hashable as object in mypy, e.g.

from typing import TYPE_CHECKING
if TYPE_CHECKING:
    Hashable = object
else:
    from typing import Hashable

@sametmax
Copy link
Author

sametmax commented Nov 7, 2016

I don't. I'll take the workaround, but I'm all for a clean solution. So if I have to wait for structural type checking to land, I'll wait. I came accross several issues linked to duck typing, so I guess they all require structural type checking. I can # type: ignore those for now.

@gvanrossum
Copy link
Member

So I'm not sure if there's a benefit to keeping this issue open then. It's waiting for a major feature to be designed and land, so it'll just stay open for a long time, and once that feature lands, it's presumably a typeshed issue to mark up Hashable as a protocol, not an additional mypy action item.

@sametmax
Copy link
Author

sametmax commented Nov 7, 2016

Right. If you need beta testers for the feature in the future, I'll spend some time doing it. I'm currently using a lot asyncio and mypy for various projects, and testing is the least I can do.

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

No branches or pull requests

2 participants