pathlib: make visit() independent of py.path.local, use os.scandir

`os.scandir()`, introduced in Python 3.5, is much faster than
`os.listdir()`. See https://www.python.org/dev/peps/pep-0471/.

It also has a `DirEntry` which can be used to further reduce syscalls in
some cases.
This commit is contained in:
Ran Benita
2020-07-05 23:11:47 +03:00
parent c15bb5d3de
commit 3633b691d8
4 changed files with 26 additions and 22 deletions

View File

@@ -560,14 +560,14 @@ def resolve_package_path(path: Path) -> Optional[Path]:
def visit(
path: py.path.local, recurse: Callable[[py.path.local], bool],
) -> Iterator[py.path.local]:
"""Walk path recursively, in breadth-first order.
path: str, recurse: Callable[["os.DirEntry[str]"], bool]
) -> Iterator["os.DirEntry[str]"]:
"""Walk a directory recursively, in breadth-first order.
Entries at each directory level are sorted.
"""
entries = sorted(path.listdir())
entries = sorted(os.scandir(path), key=lambda entry: entry.name)
yield from entries
for entry in entries:
if entry.check(dir=1) and recurse(entry):
yield from visit(entry, recurse)
if entry.is_dir(follow_symlinks=False) and recurse(entry):
yield from visit(entry.path, recurse)