Coverage for  / home / jenkins / .local / lib / python3.10 / site-packages / hyper_parallel / codegen / hash.py: 47%

19 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-10-25 05:45 +0800

1# Copyright 2026 Huawei Technologies Co., Ltd 

2# Licensed under the Apache License, Version 2.0 

3# ============================================================================ 

4"""Signature and file-hash helpers for codegen artifacts. 

5 

6``signature_from_spec`` is the single source of truth for artifact reuse: 

7same canonical spec => same signature => artifact hit. Any change to the 

8source modeling file, parallel topology, override set, or checkpoint 

9transform flags must change the signature. 

10""" 

11from __future__ import annotations 

12 

13import hashlib 

14import json 

15 

16 

17def sha256_file(path: str) -> str: 

18 """Compute the sha256 of a file's bytes.""" 

19 digest = hashlib.sha256() 

20 with open(path, "rb") as handle: 

21 for chunk in iter(lambda: handle.read(1 << 20), b""): 

22 digest.update(chunk) 

23 return digest.hexdigest() 

24 

25 

26def sha256_text(text: str) -> str: 

27 """Compute the sha256 of a UTF-8 text payload.""" 

28 return hashlib.sha256(text.encode("utf-8")).hexdigest() 

29 

30 

31def canonical_json(data: object) -> str: 

32 """Stable JSON serialization (sorted keys, no whitespace). 

33 

34 Used for signature inputs — key order must not affect the digest. 

35 """ 

36 return json.dumps(data, sort_keys=True, separators=(",", ":"), ensure_ascii=True) 

37 

38 

39def signature_from_spec(spec: object, *, prefix: int = 12) -> str: 

40 """Compute the artifact signature from a canonical spec, first ``prefix`` hex chars. 

41 

42 ``spec`` may be any JSON-serializable object (typically a 

43 :class:`CodegenSpec` ``to_dict()`` result or its canonical projection). 

44 """ 

45 return sha256_text(canonical_json(spec))[:prefix] 

46 

47 

48def file_line_count(path: str) -> int: 

49 """Count lines in a text file.""" 

50 with open(path, "r", encoding="utf-8") as handle: 

51 return sum(1 for _ in handle) 

52 

53 

54__all__ = [ 

55 "canonical_json", 

56 "file_line_count", 

57 "sha256_file", 

58 "sha256_text", 

59 "signature_from_spec", 

60]