Rev | Line | |
---|
[1055] | 1 |
|
---|
| 2 |
|
---|
| 3 | from collections.abc import Iterator
|
---|
| 4 | from itertools import tee
|
---|
[1286] | 5 | from typing import Tuple, List, Collection, Dict, Set, Type
|
---|
[1055] | 6 |
|
---|
| 7 | def safehash(obj)->int:
|
---|
| 8 | '''
|
---|
| 9 | Tool to take a hash of an object in a safe way.
|
---|
| 10 | The idea is that it intercepts non-hashable types
|
---|
| 11 | and works around it.
|
---|
| 12 | '''
|
---|
| 13 | try:
|
---|
| 14 | # first try the dumb way, because the safe way is expensive
|
---|
[1075] | 15 | # see also #357
|
---|
| 16 | return obj.__hash__()
|
---|
[1055] | 17 | except TypeError:
|
---|
[1059] | 18 | # the constants are to distinguish between the types
|
---|
| 19 | if isinstance(obj, Set): #order irrelevant
|
---|
| 20 | return 17+sum([safehash(it) for it in obj])
|
---|
| 21 | if isinstance(obj, Dict): # order irrelevant.
|
---|
| 22 | return 133+sum([safehash(item) for item in obj.items() ])
|
---|
[1169] | 23 | if isinstance(obj, List) or isinstance(obj, tuple): # order is important
|
---|
[1059] | 24 | return 31+hash( tuple ( safehash(elt) for elt in obj ) )
|
---|
[1286] | 25 | if isinstance(obj, type):
|
---|
| 26 | return hash(obj)
|
---|
[1059] | 27 | raise ValueError("Type not yet handled: "+str(obj)) |
---|
Note:
See
TracBrowser
for help on using the repository browser.