Skip to main content

atomicreplace

atomicreplace safely replaces files without exposing readers to partial content. It uses private same-directory staging, explicit durability controls, permission preservation, and strict target validation.

Unlike basic atomic-write wrappers, atomicreplace refuses unsafe target types, handles permissions explicitly, distinguishes committed post-replacement errors, and validates behavior across Linux, macOS, and Windows.

from atomicreplace import replace_text

rendered_settings = "enabled = true\n"
replace_text("settings.toml", rendered_settings, durability="data")

Or write incrementally:

from atomicreplace import atomic_open

rendered_manifest = '{"files": []}\n'
with atomic_open("manifest.json", "w", permissions=0o600) as file:
    file.write(rendered_manifest)

The target remains unchanged until the context exits successfully. A staging file is created beside the target and committed with os.replace().

Install

python -m pip install atomicreplace

Python 3.9 or newer is supported. Runtime dependencies: none.

API

replace_bytes(path, data, *, permissions=None,
              preserve_permissions=True, durability="none",
              allow_hardlinks=False)

replace_text(path, text, *, encoding="utf-8", errors="strict", newline=None,
             permissions=None, preserve_permissions=True,
             durability="none", allow_hardlinks=False)

atomic_open(path, mode="w", *, buffering=-1, encoding=None, errors=None,
            newline=None, permissions=None, preserve_permissions=True,
            durability="none", allow_hardlinks=False)

Only w, wt, and wb modes are accepted. Append, update, exclusive-create, and read modes would require different concurrency semantics and are rejected.

Durability

  • none: flush Python buffers and atomically replace the directory entry.
  • data: additionally call os.fsync() on the staged file before replacement.
  • full: additionally synchronize the parent directory after replacement.

full is available on POSIX systems. It is rejected before staging on platforms where the standard library cannot synchronize a directory. A DirectorySyncError means the new target is already committed, but the full crash-durability request was not completed.

Atomic visibility and crash durability are different properties. Filesystems, network mounts, virtual filesystems, storage controllers, and hardware may provide weaker behavior than the host operating-system API suggests.

Safety behavior

  • The target path is mandatory and is bound to an absolute path when the operation is created.
  • The staging file is created in the target directory with private permissions.
  • Existing regular-file permissions are preserved by default; new files default to 0o600.
  • Symbolic-link targets are refused. Parent-directory symlinks are not resolved; callers must trust the directory path they supply.
  • Multi-linked regular files are refused by default because replacement changes only one directory entry. Use allow_hardlinks=True only when that is intended.
  • Directories, devices, FIFOs, sockets, and other non-regular targets are refused.
  • Special permission bits, ownership, ACLs, extended attributes, timestamps, alternate data streams, and platform-specific metadata are not copied.
  • Concurrent writers are last-successful-replacement-wins. On Windows, same-process writes to the same lexical target are internally serialized for the lifetime of each context to reduce replacement sharing failures; nested use by the same thread is supported and the outer successful replacement wins. This implementation safety mechanism neither coordinates other processes nor provides locking or compare-and-swap semantics for logical updates.
  • A process terminated before replacement can leave a .atomicreplace-*.tmp staging file in the target directory. Existing target data remains untouched.

The containing directory must be trusted. No path-based API can defend a file inside a directory whose entries an attacker may freely rename or replace.

Development and release trust

The runtime package has no dependencies. Development tools are exact, optional dependencies:

python -m pip install -e ".[dev]"
python tools/ci.py all

Every pull request is tested on Python 3.9 through 3.14 on Linux, macOS, and Windows. GitHub Actions are pinned to immutable commit SHAs. Releases are rebuilt and retested from the exact tag, checked for metadata and archive integrity, installed in isolation, attested, and published to PyPI with OIDC Trusted Publishing rather than a stored API token.

See docs/CI_ARCHITECTURE.md, docs/GITHUB_SETUP.md, and docs/RELEASING.md.

Metadata

Release files for atomicreplace 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for atomicreplace 0.1.0
File Size Uploaded
atomicreplace-0.1.0.tar.gz 17.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for atomicreplace 0.1.0
File Interpreter ABI Platform
atomicreplace-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 29.2 kB

Release files / atomicreplace-0.1.0.tar.gz

Download URL atomicreplace-0.1.0.tar.gz
Size 17.3 kB
Tags Source
SHA-256 checksum
How to use checksums
2c6779d920d4920ecfcd0e7c57c0f55937de1b176af5428b5427c1745a4b3473
BLAKE2b-256 checksum
How to use checksums
fa3dddce07abb1dad56fdfd6c72adcd392c20c80c4dc15b811f6361ce3e62a2e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.

Transparency log

Release files / atomicreplace-0.1.0-py3-none-any.whl

Download URL atomicreplace-0.1.0-py3-none-any.whl
Size 11.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
39a66a040e439a9aa0b357bc3b9695bf06a03b1536c35ab223146d409fc4fda0
BLAKE2b-256 checksum
How to use checksums
fc17518728dbd6bfdb1cad3b11218f570ce11474596fc172eb1784885be51281
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page