This rule raises an issue when an unhashable object is used as a set member or dictionary key.

== Why is this an issue?

The hash value of an object is an integer returned by its ``++__hash__++`` method. Objects that are considered equal to each other (as per the ``++__eq__++`` method) should have the same hash value.

Whenever using an object as a dictionary key or inserting it into a set, the hash value of that object will be used to derive a bucket in which the object will be inserted.

When attempting to insert an unhashable object into a set, a `TypeError` will be raised instead. 

If an object defines a ``++__hash__++`` method derived from mutable properties, no `TypeError` will be raised. However, having a mutable hash value should never be done as this would prevent dictionaries and set from retrieving the object.

== How to fix it

Make sure to always use hashable (and immutable) objects as dictionary keys or set members. 

=== Code examples

==== Noncompliant code example

[source,python,diff-id=1,diff-type=noncompliant]
----
def foo():
    my_list = [1,2,3]
    my_set = {my_list}  # Noncompliant: list is not hashable.

----

==== Compliant solution

[source,python,diff-id=1,diff-type=compliant]
----
def foo():
    my_list = [1,2,3]
    my_set = set(my_list) # This will insert the elements of my_list into a new set.

# OR

def foo():
    my_tuple = (1,2,3)
    my_set = {my_tuple} # tuples are immutable and hashable. They can be inserted into sets.
----

== Resources

=== Documentation

* Python Documentation - https://docs.python.org/3/reference/datamodel.html#object.__hash__[object.__hash__]
* Python Documentation - https://docs.python.org/3/library/functions.html#hash[the hash built-in function]
