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