hhh134's picture
Upload HCL open-source release (part 3)
087e4a0 verified
Raw History Blame Contribute Delete
1.62 kB
from __future__ import annotations
import hashlib
import json
from pathlib import Path
from typing import Any
def stable_json_hash(value: Any) -> str:
canonical = json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
return hashlib.sha256(canonical.encode("utf-8")).hexdigest()
def json_clone(value: Any) -> Any:
return json.loads(json.dumps(value, ensure_ascii=False))
def atomic_write_json(path: str | Path, value: Any) -> None:
"""Atomically replace one JSON document in its destination directory."""
destination = Path(path)
destination.parent.mkdir(parents=True, exist_ok=True)
temporary = destination.with_name(f".{destination.name}.tmp")
try:
with temporary.open("w", encoding="utf-8") as f:
json.dump(value, f, ensure_ascii=False, indent=2)
f.write("\n")
f.flush()
temporary.replace(destination)
finally:
if temporary.exists():
temporary.unlink()
def atomic_write_jsonl(path: str | Path, records: list[dict[str, Any]]) -> None:
"""Atomically replace a JSONL snapshot without publishing a partial line."""
destination = Path(path)
destination.parent.mkdir(parents=True, exist_ok=True)
temporary = destination.with_name(f".{destination.name}.tmp")
try:
with temporary.open("w", encoding="utf-8") as f:
for record in records:
f.write(json.dumps(record, ensure_ascii=False) + "\n")
f.flush()
temporary.replace(destination)
finally:
if temporary.exists():
temporary.unlink()