/
hashing.py
45 lines (32 loc) · 1.24 KB
/
hashing.py
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
import hashlib
import inspect
from autocache.utils import convert_dict_to_tuple
def md5(value):
"""
Helper function that returns an MD5 hash of the passed value, allowing a
more pluggable hash implementation than requiring all hash functions to
support the `hashlib` API.
"""
return hashlib.md5(value).hexdigest()
# Callable Hashing
def bytecode_hash(function, hash=md5):
"""
Returns the hashed bytecode for the provided callable.
"""
return hash(function.func_code.co_code)
def source_hash(function, hash=md5):
"""
Returns the hashed source for the provided callable.
"""
return hash(inspect.getsource(function))
# Argument Hashing
def argument_hash(function, *args, **kwargs):
# TODO: Allow usage of a different postprocessor than MD5.
# TODO: Replace `hash` with a safe hashing implementation.
# TODO: Allow recursive conversion of dictionary to tuples, probably do the
# same for lists as well.
arguments = inspect.getcallargs(function, *args, **kwargs)
if 'kwargs' in arguments:
arguments['kwargs'] = convert_dict_to_tuple(arguments['kwargs'])
arguments = convert_dict_to_tuple(arguments)
return md5(':'.join(map(lambda value: str(hash(value)), arguments)))