"""Atomare Datei-Writes: erst .tmp im selben Verzeichnis, dann os.replace. Ein Crash hinterlässt höchstens eine .tmp-Datei — nie eine halb geschriebene Zieldatei. Die .tmp wird beim nächsten erfolgreichen Write überschrieben. """ import json import os from pathlib import Path def atomic_write_text(path: Path, text: str) -> None: tmp = path.with_name(path.name + ".tmp") with open(tmp, "w", encoding="utf-8") as f: f.write(text) f.flush() os.fsync(f.fileno()) os.replace(tmp, path) def atomic_write_json(path: Path, obj, **dumps_kwargs) -> None: atomic_write_text(path, json.dumps(obj, ensure_ascii=False, **dumps_kwargs))