(path: str)
| 144 | |
| 145 | # Recursive scandir — on Windows, DirEntry.stat() is free (no extra syscall) |
| 146 | def _scan(path: str) -> None: |
| 147 | try: |
| 148 | entries = sorted(os.scandir(path), key=lambda e: e.name) |
| 149 | except OSError: |
| 150 | return |
| 151 | subdirs: list[str] = [] |
| 152 | for entry in entries: |
| 153 | if entry.is_dir(follow_symlinks=False): |
| 154 | subdirs.append(entry.path) |
| 155 | elif entry.is_file(follow_symlinks=False) and entry.name.endswith(_EXTS): |
| 156 | try: |
| 157 | st = entry.stat() |
| 158 | h.update(f"{entry.path}:{st.st_mtime:.6f}".encode()) |
| 159 | except OSError: |
| 160 | h.update(f"{entry.path}:MISSING".encode()) |
| 161 | for d in subdirs: |
| 162 | _scan(d) |
| 163 | |
| 164 | _scan(src_dir) |
| 165 |
no test coverage detected