![github-actions[bot]](/assets/img/avatar_default.png)
You can preview this rule [here](https://sonarsource.github.io/rspec/#/rspec/S6662/python) (updated a few minutes after each push). ## Review A dedicated reviewer checked the rule description successfully for: - [ ] logical errors and incorrect information - [ ] information gaps and missing content - [ ] text style and tone - [ ] PR summary and labels follow [the guidelines](https://github.com/SonarSource/rspec/#to-modify-an-existing-rule) --------- Co-authored-by: guillaume-dequenne-sonarsource <guillaume-dequenne-sonarsource@users.noreply.github.com> Co-authored-by: Guillaume Dequenne <guillaume.dequenne@sonarsource.com>
50 lines
1.7 KiB
Plaintext
50 lines
1.7 KiB
Plaintext
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]
|