Source code for simvx.core.io

"""Filesystem I/O helpers shared across the engine.

Centralises crash-safe write patterns so the IDE, scene save, asset writer,
and other consumers share one implementation. The pickle-rotation flavour
lives in ``simvx.core.save_manager.pickle_atomic`` for the (game save +
editor autosave) payloads that need .bak/.bak2 chains.
"""

from __future__ import annotations

import os
from pathlib import Path


[docs] def atomic_write_text(path: Path | str, text: str, *, encoding: str = "utf-8") -> Path: """Write ``text`` to ``path`` atomically. Writes to ``<path>.tmp``, fsyncs, then ``os.replace()`` onto the target so a crash mid-write never leaves a truncated file on disk -- either the old file or the new one is fully present at every instant. Creates parent directories as needed. Raises ``OSError`` on write failure (the temp file is best-effort cleaned). """ path = Path(path) path.parent.mkdir(parents=True, exist_ok=True) tmp_path = path.with_name(path.name + ".tmp") payload = text.encode(encoding) try: with open(tmp_path, "wb") as fh: fh.write(payload) fh.flush() os.fsync(fh.fileno()) except OSError: try: tmp_path.unlink() except OSError: pass raise os.replace(tmp_path, path) return path