summaryrefslogtreecommitdiff
path: root/django/utils/hashable.py
diff options
context:
space:
mode:
authoraspalding <aspalding@procuredhealth.com>2018-10-16 10:02:36 -0500
committerTim Graham <timograham@gmail.com>2018-10-17 11:17:50 -0400
commit217f82d7139fd32f07adbfa92c5fb383d0ade577 (patch)
tree753bd98d3cf496b43f1f719bb800bc129a2f5bc5 /django/utils/hashable.py
parent834c4ec8e4cfc43acf0525e0a4d8c914534f6afd (diff)
Refs #29838 -- Fixed make_hashable() for values that have lists or dicts nested in tuples.
And for non-hashable values that are iterable, e.g. sets.
Diffstat (limited to 'django/utils/hashable.py')
-rw-r--r--django/utils/hashable.py14
1 files changed, 12 insertions, 2 deletions
diff --git a/django/utils/hashable.py b/django/utils/hashable.py
index 859ea8073e..0bef5b003d 100644
--- a/django/utils/hashable.py
+++ b/django/utils/hashable.py
@@ -1,9 +1,19 @@
+from django.utils.itercompat import is_iterable
+
+
def make_hashable(value):
- if isinstance(value, list):
- return tuple(map(make_hashable, value))
if isinstance(value, dict):
return tuple([
(key, make_hashable(nested_value))
for key, nested_value in value.items()
])
+ # Try hash to avoid converting a hashable iterable (e.g. string, frozenset)
+ # to a tuple.
+ try:
+ hash(value)
+ except TypeError:
+ if is_iterable(value):
+ return tuple(map(make_hashable, value))
+ # Non-hashable, non-iterable.
+ raise
return value