atomic-write
A single-file Python module providing crash-safe file writes that either fully succeed or leave the previous contents intact — no partial writes, no `.tmp` residue, no torn data visible to readers.
A single-file Python module providing crash-safe file writes that either fully succeed or leave the previous contents intact — no partial writes, no `.tmp` residue, no torn data visible to readers.
The raw documents handed to every model and every judge. Read these as the source of truth.
atomic_write.py — implementation specA single-file Python module providing crash-safe file writes that
either fully succeed or leave the previous contents intact — no
partial writes, no .tmp residue, no torn data visible to readers.
atomic_write_text(path, data, *, encoding="utf-8", mode=None) -> NoneAtomically write the string data to path.
| Parameter | Type | Default | Behaviour |
|---|---|---|---|
path |
str or os.PathLike |
required | target path |
data |
str |
required | content to write |
encoding |
str |
"utf-8" |
text encoding |
mode |
int or None |
None |
if set, chmod the new file to this mode (octal). If None and the target already exists, preserve the target's existing mode; otherwise the new file gets the default umask-derived mode. |
Raises:
FileNotFoundError — parent directory doesn't exist (no temp residue)IsADirectoryError — path exists and is a directoryPermissionError — can't create temp file or replace targetOSError — any other I/O failure (disk full, etc.); temp file is cleaned upatomic_write_bytes(path, data, *, mode=None) -> NoneSame contract as atomic_write_text but for bytes. No encoding parameter.
In order, every write must:
path (not tempfile.gettempdir() — cross-filesystem os.replace is not atomic).fsync the file descriptor.os.replace(tmp, path) — atomic rename.fsync the parent directory (so the rename itself is durable).mode is None, the new file inherits the target's pre-existing mode bits.If any of steps 1–6 raise, the temp file (if it was created) must be removed before the exception propagates.
python atomic_write.py <path>
Reads stdin (bytes mode, no decoding) and writes the contents to path
atomically using the bytes API. Exits 0 on success, non-zero on any
error with a message on stderr.
Two threads (or processes) calling atomic_write_text(path, ...) with
different content must result in path containing one writer's full
content, never a mix. No reader at any wall-clock instant sees a
truncated or partially-written file.
If path is a symlink, write to the symlink target, not replace
the symlink itself. (Common gotcha: naive os.replace would replace
the symlink, breaking the link.) The temp file lives next to the
resolved target so the rename stays on the same filesystem.
from atomic_write import atomic_write_text, atomic_write_bytes
atomic_write_text("config.json", '{"version": 2}\n')
atomic_write_bytes("blob.dat", b"\x00\x01\x02")
atomic_write_text("script.sh", "#!/bin/sh\necho hi\n", mode=0o755)
echo '{"version": 2}' | python atomic_write.py config.json
atomic_write.pyRead SPEC.md in this directory. Implement atomic_write.py exactly per
spec: two library functions (atomic_write_text, atomic_write_bytes)
plus a CLI entry point for use in shell pipelines.
This task covers only atomic_write.py. Do not create helper modules,
test files, or packaging metadata.
pip install, no new dependencies.os.replace is on the same filesystem (cross-fs renames are not
atomic on POSIX).fsync'd before close, and the parent directory
must be fsync'd after the replace, so a power loss between writes
doesn't surface a missing or empty file..tmp residue
on disk after a failed call.A single file atomic_write.py at the worktree root that:
Exposes two top-level functions:
def atomic_write_text(path, data, *, encoding="utf-8", mode=None) -> None: ...
def atomic_write_bytes(path, data, *, mode=None) -> None: ...
Provides a CLI that reads stdin and writes atomically to a target path:
python atomic_write.py <path>
.tmp files remain in the dir.atomic_write.py."Fill one copy per implementation, saved as output/<label>_rubric.md.
Also write output/<label>_scores.json with the structured form (see
JUDGE_PROMPT.md).
Implementation reviewed: <label> (e.g. A, B, C)
File: implementations/<label>.py
Cite line numbers when something fails.
atomic_write.py provided as <label>.pyatomic_write_text(path, data, *, encoding="utf-8", mode=None) matches SPEC signatureatomic_write_bytes(path, data, *, mode=None) matches SPEC signaturetempfile.gettempdir() or a hardcoded /tmp)fsync'd before closefsync'd after os.replaceHard-fail result: pass / fail If fail, reasons (with line refs):
Award 1 point per item present and correct. Cite line numbers.
os.replace (not os.rename — Windows differs) for the atomic stepmode is None, the new file inherits the target's pre-existing mode bits (os.stat then os.chmod)mode is set explicitly, applies it (os.chmod) before the replaceFileNotFoundError cleanly when the parent directory doesn't exist (and leaves no temp residue)IsADirectoryError when path is an existing directorypython atomic_write.py <path> reads stdin (bytes mode) and writes atomicallytempfile.NamedTemporaryFile(dir=...) or pid+rand suffix) so two concurrent calls don't collide on the temp filenameSubtotal: __ / 10 Notes:
Subtotal: __ / 20
ship-with-cleanup / rewrite / unusable