hashable.py 706 B

123456789101112131415161718192021222324
  1. from django.utils.itercompat import is_iterable
  2. def make_hashable(value):
  3. """
  4. Attempt to make value hashable or raise a TypeError if it fails.
  5. The returned value should generate the same hash for equal values.
  6. """
  7. if isinstance(value, dict):
  8. return tuple([
  9. (key, make_hashable(nested_value))
  10. for key, nested_value in sorted(value.items())
  11. ])
  12. # Try hash to avoid converting a hashable iterable (e.g. string, frozenset)
  13. # to a tuple.
  14. try:
  15. hash(value)
  16. except TypeError:
  17. if is_iterable(value):
  18. return tuple(map(make_hashable, value))
  19. # Non-hashable, non-iterable.
  20. raise
  21. return value