files.py 916 B

12345678910111213141516171819202122232425
  1. """Écriture des fichiers gardés sur le disque."""
  2. from __future__ import annotations
  3. import contextlib
  4. import os
  5. from pathlib import Path
  6. def write_atomic(path: Path, text: str) -> None:
  7. """Écrit text dans path sans jamais laisser de fichier à moitié écrit : dans un fichier temporaire,
  8. envoyé jusqu'au disque (fsync) avant d'être renommé, sinon une coupure de courant juste après le
  9. renommage pourrait laisser un fichier vide. Le fichier temporaire est retiré si l'écriture échoue."""
  10. path.parent.mkdir(parents=True, exist_ok=True)
  11. tmp = path.with_suffix(path.suffix + ".tmp")
  12. try:
  13. with open(tmp, "w", encoding="utf-8") as file:
  14. file.write(text)
  15. file.flush()
  16. os.fsync(file.fileno())
  17. os.replace(tmp, path)
  18. except OSError:
  19. with contextlib.suppress(OSError):
  20. tmp.unlink(missing_ok=True)
  21. raise