Master

Atomic replace

A file that other readers use must never be seen half written. The move is a rename, and the rename is the only switch point.

What you will see

0o644

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Check the swap rules.

1

Swap runs.

import os os.replace("a", "a") print("swapped")

Before you run it, say out loud what it will print. Then open the answer.

What it prints
swapped
2

Name exists after.

import os os.replace("a", "a") print(os.path.exists("a"))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
True
3

Both versions read.

rows = ["old", "new"] print(len(rows))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
2
4

Permissions shown.

print(oct(0o644))

Before you run it, say out loud what it will print. Then open the answer.

What it prints
0o644

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

Write the new bytes to a temp name in the same folder, then rename. The rename is the only moment the file changes.
1 write a temp file
↓
2 keep the temp name
↓
3 rename in place
↓
4 clean a failed swap
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

import os sets nothing on screen
os.replace("a", "a") sets nothing on screen
print("swapped") swapped
Why this works
One switch point

A rename changes what a name points to in one step. Every earlier write is invisible to readers, which is what makes the update safe.

Cleanup is part of it

A failed swap leaves a temp file behind. Name it so a later run can find and remove it.

Examples

Write then swap

import os
os.replace("a", "a")
print("swapped")

The new bytes live in a temp name until the swap. Readers see old or new, never both.

Same folder matters

import os
os.replace("a", "a")
print(os.path.exists("a"))

A rename inside one folder is atomic. Across folders it becomes a copy, which is not.

Two readers agree

rows = ["old"]
new = ["new"]
print(rows[0], new[0])

Each reader opens one version. Neither sees a file that is part old and part new.

The temp name is kept

import os
os.replace("a", "a")
print("kept")

If the swap fails, the temp file stays. Clean it up or the folder fills with junk.

Permissions travel

import os
mode = 0o644
print(oct(mode))

A new file gets new permissions. Copy the mode from the old file when it matters.

Readers must re-open

rows = ["v1", "v2"]
print(len(rows))

A reader holding an open handle keeps the old bytes. Re-open to see the swap.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Failures that matter
Previous Lesson
Failures that matter
Next Lesson
Binary and text modes
Binary and text modes →