From e9a40a3af342ed8a53f4b010f6329bbecd06a527 Mon Sep 17 00:00:00 2001 From: imSp4rky Date: Thu, 30 Jul 2026 17:11:18 -0600 Subject: [PATCH] perf: speed up the code hash with sha1 and a plain file reader --- tests/core/test_code_hash.py | 2 +- unshackle/core/__init__.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/core/test_code_hash.py b/tests/core/test_code_hash.py index 9aa10aa3..68ee6d92 100644 --- a/tests/core/test_code_hash.py +++ b/tests/core/test_code_hash.py @@ -16,7 +16,7 @@ pytestmark = pytest.mark.unit def test_is_hex_and_stable() -> None: first = code_hash() - assert len(first) == 32 + assert len(first) == 40 assert int(first, 16) >= 0 assert first == code_hash() diff --git a/unshackle/core/__init__.py b/unshackle/core/__init__.py index 5005e996..130bca20 100644 --- a/unshackle/core/__init__.py +++ b/unshackle/core/__init__.py @@ -16,12 +16,13 @@ def _raise(error: OSError) -> None: def code_files() -> list[str]: """Framework source paths relative to the package root, in a platform-stable order.""" + pkg = str(_PKG) rels = ["__main__.py"] for name in _CODE_DIRS: - for root, dirs, files in os.walk(_PKG / name, onerror=_raise): + for root, dirs, files in os.walk(os.path.join(pkg, name), onerror=_raise): dirs[:] = [d for d in dirs if d != "__pycache__"] - rel = os.path.relpath(root, _PKG) - rels.extend(os.path.join(rel, f).replace(os.sep, "/") for f in files if f.endswith(".py")) + rel = os.path.relpath(root, pkg).replace(os.sep, "/") + rels.extend(f"{rel}/{f}" for f in files if f.endswith(".py")) return sorted(rels) @@ -30,17 +31,19 @@ def code_hash( read: Optional[Callable[[str], bytes]] = None, ) -> str: """ - md5 of the framework source. Identifies the running code, not the release it claims to be. + sha1 of the framework source. Two installs on the same version differ here if their code does. Pass `files` and `read` to digest a different byte source, such as blobs from git history (see tools/resolve_code_hash.py). Returns "" when the source cannot be read. """ if read is None: + pkg = str(_PKG) def read(rel: str) -> bytes: - return (_PKG / rel).read_bytes() + with open(os.path.join(pkg, rel), "rb") as fh: + return fh.read() - digest = hashlib.md5(usedforsecurity=False) + digest = hashlib.sha1(usedforsecurity=False) try: for rel in code_files() if files is None else files: digest.update(rel.encode())