Return max mtime of any source file under root (stdlib only). Recursively scans root directory tree and returns the maximum modification time of any source file matching the given extensions. Skips directories in SKIP_DIR_NAMES and those starting with prefixes in SKIP_DIR_PREFIXES.
(root: Path, exts: frozenset = CPP_EXTS)
| 43 | |
| 44 | |
| 45 | def max_file_mtime(root: Path, exts: frozenset = CPP_EXTS) -> float: |
| 46 | """Return max mtime of any source file under root (stdlib only). |
| 47 | |
| 48 | Recursively scans root directory tree and returns the maximum modification |
| 49 | time of any source file matching the given extensions. Skips directories |
| 50 | in SKIP_DIR_NAMES and those starting with prefixes in SKIP_DIR_PREFIXES. |
| 51 | |
| 52 | Uses os.scandir() + stack-based traversal (not recursive) to minimize |
| 53 | memory overhead on large directory trees (e.g., tests/ with 329+ files). |
| 54 | |
| 55 | Args: |
| 56 | root: Root directory to scan. |
| 57 | exts: Frozenset of file extensions to match (default: C++ extensions). |
| 58 | |
| 59 | Returns: |
| 60 | Maximum file mtime (float), or 0.0 if no files match. |
| 61 | """ |
| 62 | |
| 63 | def _should_skip_dir(name: str) -> bool: |
| 64 | """Check if directory should be skipped from traversal.""" |
| 65 | return name in SKIP_DIR_NAMES or any( |
| 66 | name.startswith(pfx) for pfx in SKIP_DIR_PREFIXES |
| 67 | ) |
| 68 | |
| 69 | max_mtime = 0.0 |
| 70 | stack = [str(root)] |
| 71 | while stack: |
| 72 | try: |
| 73 | with os.scandir(stack.pop()) as it: |
| 74 | for entry in it: |
| 75 | try: |
| 76 | if entry.is_dir(follow_symlinks=False): |
| 77 | if not _should_skip_dir(entry.name): |
| 78 | stack.append(entry.path) |
| 79 | elif entry.is_file(follow_symlinks=False): |
| 80 | _, ext = os.path.splitext(entry.name) |
| 81 | if ext.lower() in exts: |
| 82 | mtime = entry.stat(follow_symlinks=False).st_mtime |
| 83 | max_mtime = max(max_mtime, mtime) |
| 84 | except OSError: |
| 85 | pass |
| 86 | except OSError: |
| 87 | pass |
| 88 | return max_mtime |
| 89 | |
| 90 | |
| 91 | def max_file_mtime_flat(root: Path, exts: frozenset = CPP_EXTS) -> float: |
no test coverage detected