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

How to represent that list is not hashable #74

Closed
JukkaL opened this issue Apr 6, 2015 · 4 comments
Closed

How to represent that list is not hashable #74

JukkaL opened this issue Apr 6, 2015 · 4 comments
Labels
resolution: wontfix A valid issue that most likely won't be resolved for reasons described in the issue

Comments

@JukkaL
Copy link
Contributor

JukkaL commented Apr 6, 2015

collections.abc defines Hashable which should correspond to hashable objects. However, this is a little tricky, since hashability is not an always inherited property. Consider object vs. list:

>>> from collections.abc import *
>>> issubclass(object, Hashable)
True
>>> issubclass(list, object)
True
>>> issubclass(list, Hashable)
False

There is currently no way defined in the PEP for representing the fact that list is not hashable. We could have object be a subclass of Hashable, but without some further rules this would make list hashable as well.

Here is one potential way of specifying this in code or stubs:

class list(...)
    ...
    def __hash__(self):
        raise NotImplementedError()  # A type checker should recognize this

We could still not always check hashability reliably. For example, a variable with type object should probably be considered hashable, but it could actually be a list, which is not hashable. This is probably a very minor problem, though. Having a way of rejecting Dict[List[int], int] would be nice. We'd also need something like bounded polymorphism, though, so that we could they that a dictionary key type must a subtype of Hashtable.

Another alternative would be to not make object hashable, but since hash(object()) is okay, it doesn't sound right.

@gvanrossum
Copy link
Member

In real code the convention (explicitly checked for by the hash() builtin) is that if you set hash to None that means the class is not hashable. Literally:

class Foo(object):
    __hash__ = None
    def __eq__(self, other): return random() < 0.5

@JukkaL
Copy link
Contributor Author

JukkaL commented Apr 6, 2015

Ah, I didn't know about that. That sounds like a good convention that should be supported by type checkers.

@vladiibine
Copy link

an abstract base class, UnHashable, which describes unhashable objects perhaps?
We could always create abc's for describing anything we wanted, and make them support the [] operator for getting an object to use in the typing system... or at least I'd hope we can extend the already suggested classes.

@gvanrossum gvanrossum added the resolution: wontfix A valid issue that most likely won't be resolved for reasons described in the issue label May 18, 2015
@gvanrossum
Copy link
Member

I don't think we need to add this explicitly to the PEP. The __hash__ = None convention is sufficient. (It is documented here: https://docs.python.org/3/reference/datamodel.html#object.__hash__)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
resolution: wontfix A valid issue that most likely won't be resolved for reasons described in the issue
Projects
None yet
Development

No branches or pull requests

3 participants