forked from cool-RR/python_toolbox
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheat_hash.py
More file actions
51 lines (36 loc) · 1.35 KB
/
cheat_hash.py
File metadata and controls
51 lines (36 loc) · 1.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Copyright 2009-2017 Ram Rachum.
# This program is distributed under the MIT license.
'''
Defines the `cheat_hash` function for cheat-hashing mutable objects.
See its documentation for more details.
'''
from .cheat_hash_functions import (cheat_hash_dict, cheat_hash_object,
cheat_hash_sequence, cheat_hash_set)
infinity = float('inf')
dispatch_map = {
object: cheat_hash_object,
tuple: cheat_hash_sequence,
list: cheat_hash_sequence,
dict: cheat_hash_dict,
set: cheat_hash_set
}
'''`dict` mapping from a type to a function that cheat-hashes it.'''
def cheat_hash(thing):
'''
Cheat-hash an object. Works on mutable objects.
This is a replacement for `hash` which generates something like an hash for
an object, even if it is mutable, unhashable and/or refers to
mutable/unhashable objects.
This is intended for situtations where you have mutable objects that you
never modify, and you want to be able to hash them despite Python not
letting you.
'''
thing_type = type(thing)
matching_types = \
[type_ for type_ in dispatch_map if issubclass(thing_type, type_)]
mro = thing_type.mro()
matching_type = min(
matching_types,
key=lambda type_: (mro.index(type_) if type_ in mro else infinity)
)
return dispatch_map[matching_type](thing)