summaryrefslogtreecommitdiff
path: root/morphlib/cachekeycomputer.py
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2012-05-11 13:52:42 +0100
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2012-05-11 13:52:42 +0100
commite5fefead3a643085055e8419f330e5756268013c (patch)
tree51297ba37b8dcc3031da8829d74894ee13f600ba /morphlib/cachekeycomputer.py
parent8a02512e83750f6f057b0e0bb21d4d54ee619c10 (diff)
downloadmorph-e5fefead3a643085055e8419f330e5756268013c.tar.gz
Fix stringifying morphologies to be deterministic
Previously we were stringifying complex values (lists, dicts) by using whatever Python produces, but different runs and versions of Python may convert them differently, particularly dicts. We now do it manually.
Diffstat (limited to 'morphlib/cachekeycomputer.py')
-rw-r--r--morphlib/cachekeycomputer.py22
1 files changed, 18 insertions, 4 deletions
diff --git a/morphlib/cachekeycomputer.py b/morphlib/cachekeycomputer.py
index a1c2ebd6..6ae2b107 100644
--- a/morphlib/cachekeycomputer.py
+++ b/morphlib/cachekeycomputer.py
@@ -89,12 +89,26 @@ class CacheKeyComputer(object):
if kind == 'chunk':
keys['ref'] = artifact.source.sha1
elif kind in ('system', 'stratum'):
- checksum = hashlib.sha1()
morphology = artifact.source.morphology
- getkey = lambda s: [ord(c) for c in s]
- for key in sorted(morphology.keys(), key=getkey):
- checksum.update('%s=%s' % (key, morphology[key]))
+ le_dict = dict((k,morphology[k]) for k in morphology.keys())
+ checksum = hashlib.sha1(self._stringify(le_dict))
keys['morphology-sha1'] = checksum.hexdigest()
return keys
+ def _stringify(self, value):
+ if type(value) in [str, unicode, int]:
+ return str(value)
+ elif value is None:
+ return ''
+ elif type(value) is list:
+ return '[' + ','.join(self._stringify(x) for x in value) + ']'
+ elif type(value) is dict:
+ keys = value.keys()
+ keys.sort(key=lambda s: [ord(c) for c in s])
+ pairs = ['%s:%s' % (self._stringify(k), self._stringify(value[k]))
+ for k in keys]
+ return '{' + ','.join(pairs) + '}'
+ else: # pragma: no cover
+ raise NotImplementedError(
+ 'type %s is not stringified' % type(value))