diff --git a/.jules/bolt.md b/.jules/bolt.md index 63607c3..0730d9b 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -60,3 +60,6 @@ ## 2026-06-25 - [Optimize Path.exists() when paired with stat()] **Learning:** Checking `Path.exists()` before `Path.stat()` introduces a redundant system call because `exists()` internally uses `stat()`. **Action:** Rely on catching the `OSError` from `Path.stat()` to simultaneously check for existence and retrieve file attributes, saving measurable I/O overhead on large filesystems. +## 2024-06-27 - [Avoid unnecessary lstat calls when filtering directories] +**Learning:** During directory traversal optimization (e.g. `os.walk`), doing system calls like `os.lstat()` unconditionally just to check for symlinks causes substantial I/O overhead. In `find_candidates`, `is_symlink` was only needed if exact exclusions were configured (`excluded_exact_strs`), yet `os.lstat()` ran for every single subdirectory. +**Action:** Always move heavy filesystem checks (`stat`, `lstat`, `realpath`) inside conditional blocks that actually require them. Don't pre-compute metadata if there's a chance the downstream logic will skip it. diff --git a/media_shrinker.py b/media_shrinker.py index 3eede1d..c530cca 100644 --- a/media_shrinker.py +++ b/media_shrinker.py @@ -222,13 +222,13 @@ def find_candidates( d_path_str = os.path.join(dirpath_str, d) - try: - d_stat = os.lstat(d_path_str) - is_symlink = stat.S_ISLNK(d_stat.st_mode) - except OSError: - continue - if excluded_exact_strs: + try: + d_stat = os.lstat(d_path_str) + is_symlink = stat.S_ISLNK(d_stat.st_mode) + except OSError: + continue + if not is_symlink: resolved_d_str = os.path.join(resolved_dir_str, d) else: diff --git a/tests/test_media_shrinker.py b/tests/test_media_shrinker.py index 1b202d2..b5fe254 100644 --- a/tests/test_media_shrinker.py +++ b/tests/test_media_shrinker.py @@ -196,7 +196,7 @@ def flaky_lstat(path): with patch("os.lstat", flaky_lstat): candidates = [ p[0].relative_to(root) - for p in find_candidates(root, include_under_limit=True) + for p in find_candidates(root, include_under_limit=True, exclude_paths=[root / "some_exclude"]) ] self.assertEqual(candidates, [Path("good.mp3")])