[rtems-central commit] items: Add Item.digest()
Sebastian Huber
sebh at rtems.org
Mon Dec 14 11:05:09 UTC 2020
Module: rtems-central
Branch: master
Commit: 2ac02c3aac52129b58ad20c9d5a8163596f768e6
Changeset: http://git.rtems.org/rtems-central/commit/?id=2ac02c3aac52129b58ad20c9d5a8163596f768e6
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Sun Dec 13 14:24:20 2020 +0100
items: Add Item.digest()
---
rtemsspec/items.py | 31 +++++++++++++++++++++++++++++++
rtemsspec/tests/test_items_item.py | 13 +++++++++++++
2 files changed, 44 insertions(+)
diff --git a/rtemsspec/items.py b/rtemsspec/items.py
index 2bbf084..85a713f 100644
--- a/rtemsspec/items.py
+++ b/rtemsspec/items.py
@@ -25,6 +25,7 @@
# POSSIBILITY OF SUCH DAMAGE.
from contextlib import contextmanager
+import hashlib
import os
import pickle
import string
@@ -136,6 +137,29 @@ def normalize_key_path(key_path: str, prefix: str = "") -> str:
return os.path.normpath(key_path)
+_TYPES = {
+ type(True): "B".encode("utf-8"),
+ type(1.0): "F".encode("utf-8"),
+ type(1): "I".encode("utf-8"),
+ type(None): "N".encode("utf-8"),
+ type(""): "S".encode("utf-8"),
+}
+
+
+def _hash_data(data, state) -> None:
+ if isinstance(data, list):
+ for value in data:
+ _hash_data(value, state)
+ elif isinstance(data, dict):
+ for key, value in sorted(data.items()):
+ if not key.startswith("_"):
+ state.update(key.encode("utf-8"))
+ _hash_data(value, state)
+ else:
+ state.update(_TYPES[type(data)])
+ state.update(str(data).encode("utf-8"))
+
+
class Item:
""" Objects of this class represent a specification item. """
@@ -174,6 +198,13 @@ class Item:
""" Returns the cache of the items. """
return self._cache
+ @property
+ def digest(self) -> str:
+ """ Returns the digest of the item data. """
+ state = hashlib.sha512()
+ _hash_data(self._data, state)
+ return state.hexdigest()
+
def get(self, key: str, default: Any) -> Any:
"""
Gets the attribute value if the attribute exists, otherwise the
diff --git a/rtemsspec/tests/test_items_item.py b/rtemsspec/tests/test_items_item.py
index f2a137d..9a7c119 100644
--- a/rtemsspec/tests/test_items_item.py
+++ b/rtemsspec/tests/test_items_item.py
@@ -91,6 +91,19 @@ def test_cache():
assert item.cache == item_cache
+def test_digest():
+ i = Item(EmptyItemCache(), "i", {})
+ assert i.digest == "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
+ i["_ignored"] = "nix"
+ assert i.digest == "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
+ i["a"] = {"b": ["c", 1, False, 1.25], "d": None}
+ assert i.digest == "24944e62a4e79b109c5fa97264b8c2fd694a630ede9a82ca7de36a64d01cbc902d29611490cef78e915b44b022b622de058fed2e4bdda394cb37ab9636d06925"
+ i["a"] = {"b": ["e", 1, False, 1.25], "d": None}
+ assert i.digest == "da696508ae767be7d34f16d51a2fe151a942c213596f5de4baf3c048ee519dd97dc19ab813c8730b861fad4c9c82f18652ad87402c84f80aaa59d24f3ed83c20"
+ i["a"] = {"b": ["e", "1", False, 1.25], "d": None}
+ assert i.digest == "7404cafe87a132de131d1e88170ce6d671de36bba811f9a10892a82a21a8e923f7596838d0f9cced24fe34620485603165efd9f64fffb2363c96253fd640b086"
+
+
def test_get_key_path():
data = {}
data["a"] = {"b": "c", "d": [1, 2, 3]}
More information about the vc
mailing list