hashable.py 740 B

1234567891011121314151617181920212223242526
  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. [
  10. (key, make_hashable(nested_value))
  11. for key, nested_value in sorted(value.items())
  12. ]
  13. )
  14. # Try hash to avoid converting a hashable iterable (e.g. string, frozenset)
  15. # to a tuple.
  16. try:
  17. hash(value)
  18. except TypeError:
  19. if is_iterable(value):
  20. return tuple(map(make_hashable, value))
  21. # Non-hashable, non-iterable.
  22. raise
  23. return value