Skip to content

Instantly share code, notes, and snippets.

@stavxyz
Last active October 25, 2019 15:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stavxyz/50b918092ca7e02429caeca210b1c2db to your computer and use it in GitHub Desktop.
Save stavxyz/50b918092ca7e02429caeca210b1c2db to your computer and use it in GitHub Desktop.
args / kwargs hash - works in python 2 & 3. Useful for memoizers.
def _tob(_string, enc='utf8'):
if isinstance(_string, unicode):
return _string.encode(enc)
return b'' if _string is None else bytes(_string)
def args_hash(*args, **kw):
"""Calculate a hash value from string args and kwargs.
Given the same positional arguments and keyword
arguments, this function will produce the same
hash key.
"""
items = list(args) + [i for t in sorted(kw.items()) for i in t]
items = ('__NoneType__' if _i is None else _i
for _i in items)
# All items must be strings
args_string = '|'.join(items)
return hashlib.sha1(_tob(args_string)).hexdigest()
from args_hash import args_hash
class TestArgsHash:
def test_kw_order_agnostic(self):
h1 = args_hash(
'one', 'two', 'three', four='4', five='five')
h2 = args_hash(
'one', 'two', 'three', five='five', four='4')
assert h1
assert h2
assert h1 == h2
def test_empty_case(self):
h1 = args_hash()
h2 = args_hash()
assert h1
assert h2
assert h1 == h2
def test_null_case(self):
h1 = args_hash(None)
h2 = args_hash(None)
assert h1
assert h2
assert h1 == h2
def test_null_case_kw(self):
kw = {'': None}
h1 = args_hash(None, **kw)
h2 = args_hash(None, **kw)
assert h1
assert h2
assert h1 == h2
def test_cannot_hash_non_string_int(self):
with pytest.raises(TypeError) as excinfo:
args_hash(1)
assert excinfo.type == TypeError
assert 'int found' in str(excinfo.value)
def test_cannot_hash_non_string_list(self):
with pytest.raises(TypeError) as excinfo:
args_hash([1])
assert excinfo.type == TypeError
assert 'list found' in str(excinfo.value)
def test_cannot_hash_non_string_dict(self):
with pytest.raises(TypeError) as excinfo:
args_hash({'hello': 'world'})
assert excinfo.type == TypeError
assert 'dict found' in str(excinfo.value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment