Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions marimo/_server/files/directory_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ def recurse(directory: str, depth: int = 0) -> list[FileInfo] | None:
folders: list[FileInfo] = []

for entry in entries:
# Check the limit here, not just after adding a file: a
# sibling directory's recursion may have reached it.
if file_count[0] >= self.max_files:
break

# Skip hidden files and directories
if entry.name.startswith("."):
continue
Expand Down Expand Up @@ -238,9 +243,6 @@ def recurse(directory: str, depth: int = 0) -> list[FileInfo] | None:
files.append(file_info)
# Also add to partial results for timeout recovery
self.partial_results.append(file_info)
# Check if we've reached the limit
if file_count[0] >= self.max_files:
break
except OSError as e:
LOGGER.debug(
"Error processing entry %s: %s", entry.path, e
Expand Down
25 changes: 25 additions & 0 deletions tests/_server/test_directory_scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,31 @@ def test_max_files_limit(self, test_dir: Path):
files = DirectoryScanner(str(test_dir), max_files=5).scan()
assert _count_files(files) == 5

def test_max_files_limit_recursion_at_boundary(
self, test_dir: Path, monkeypatch: pytest.MonkeyPatch
):
"""A subdir recursion that reaches max_files must not let another
top-level file slip in. Forces the ordering that only flaked in CI."""
import marimo._server.files.directory_scanner as scanner_mod

for i in range(10):
_write(test_dir / f"app{i + 3}.py", MARIMO_APP)

real_scandir = os.scandir

def ordered_scandir(path: str): # type: ignore[no-untyped-def]
entries = list(real_scandir(path))
dirs = [e for e in entries if e.is_dir()]
files = sorted(
(e for e in entries if not e.is_dir()), key=lambda e: e.name
)
# 4 files, then the nested dir (reaches the limit), then the rest.
return files[:4] + dirs + files[4:]

monkeypatch.setattr(scanner_mod.os, "scandir", ordered_scandir)
files = DirectoryScanner(str(test_dir), max_files=5).scan()
assert _count_files(files) == 5

def test_skip_common_directories(self, test_dir: Path):
skip_names = (
"venv",
Expand Down
Loading