Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python os.scandir metadata: a cached DirEntry is not a fresh file check

Last updated: 1 Oct 20265 min read
tutorial
IntermediateBy AITrove Editorial

A DirEntry can cache stat data even when the named file changes afterward.

Download Python source kit

Operation contract

The fixture scans an owned temporary directory, obtains a receipt file's size, rewrites the file with a longer payload, and reads its cached DirEntry size again. A fresh os.stat call reports the new size. The comparison isolates metadata caching from the file's current bytes.

Failure boundary

A fresh stat still does not make a later open atomic with that check. Concurrent replacement or symlink changes require descriptor-based ownership rules, not an earlier filename test. This program changes its own file and makes no claim about hostile filesystem races.

Working program

python
import os
from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as directory:
    receipt_path = Path(directory) / "receipt-47.state"
    receipt_path.write_bytes(b"ok")
    with os.scandir(directory) as entries:
        receipt_entry = next(entry for entry in entries if entry.name == receipt_path.name)
        before = receipt_entry.stat(follow_symlinks=False).st_size
        receipt_path.write_bytes(b"paid")
        cached = receipt_entry.stat(follow_symlinks=False).st_size
        fresh = os.stat(receipt_entry.path, follow_symlinks=False).st_size
    print("before", before)
    print("cached", cached)
    print("fresh", fresh)

Output

Output
before 2
cached 2
fresh 4

Costs and limits

scandir avoids some metadata system calls during enumeration; a fresh stat incurs another call. Retaining DirEntry objects for later decisions is both stale-data risk and unnecessary memory retention.

Common Mistakes

  • Do not store DirEntry metadata as a lasting file identity.
  • A fresh stat followed by a separate open still permits a race.
  • Directory enumeration order is unspecified; sort names when output order matters.

Connected lessons

Test this contract.

Continue with Python POSIX dir_fd and O_NOFOLLOW: reject a final symlink on an owned open.

python
scandir-stale-metadata
Storage details