"""JSON 파일을 안전하게 저장하는 공통 유틸리티.""" import json import os import tempfile from pathlib import Path from typing import Any def atomic_write_json(path: str | Path, value: Any) -> None: """같은 디렉터리의 임시 파일을 교체하여 JSON을 원자적으로 저장한다.""" target = Path(path) target.parent.mkdir(parents=True, exist_ok=True) temporary_path: Path | None = None try: with tempfile.NamedTemporaryFile( mode="w", encoding="utf-8", dir=target.parent, prefix=f".{target.name}.", suffix=".tmp", delete=False, ) as temporary: json.dump(value, temporary, ensure_ascii=False, indent=2) temporary.write("\n") temporary.flush() os.fsync(temporary.fileno()) temporary_path = Path(temporary.name) os.replace(temporary_path, target) temporary_path = None finally: if temporary_path is not None: temporary_path.unlink(missing_ok=True)