Keep a local project scan inside its intended directory tree
Also published in our Blogger archive.
Direct answer
A project scanner should choose its traversal boundary before it begins reading entries. Path.is_symlink() lets this example skip a directory entry that points outside the temporary root. The normal case reports only inside.py; the symbolic-link branch is either skipped or, on platforms where links cannot be created, reported as unavailable rather than silently followed.
A symlink is the relevant edge case because a lexical path under project/ can resolve to another tree. Filtering the entry before recursion is simpler to review than discovering the escape after files have already been visited.
This snippet is intentionally shallow: it does not recursively walk directories, resolve hard links, or establish a sandbox against hostile filesystem races. For a broader scanner, maintain a no-follow rule at every descent and record skipped paths in a non-sensitive form. The example only demonstrates the policy for one directory entry.
Complete example
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
root = Path(directory) / "project"
outside = Path(directory) / "outside"
root.mkdir()
outside.mkdir()
(root / "inside.py").write_text("x", encoding="utf-8")
(outside / "secret.py").write_text("x", encoding="utf-8")
link = root / "linked"
try:
link.symlink_to(outside, target_is_directory=True)
except OSError:
skipped = "symlink-unavailable"
else:
visible = [item.name for item in root.iterdir() if not item.is_symlink()]
assert visible == ["inside.py"]
skipped = "symlink-skipped"
print(f"files=1 {skipped}")
Expected stdout:
files=1 symlink-skipped
Sources
Prepared with AI assistance. The example uses synthetic data; its stated limits apply.