Skip to content

Commit 30f0643

Browse files
authored
pythonGH-117727: Speed up pathlib.Path.iterdir() by using os.scandir() (python#117728)
Replace use of `os.listdir()` with `os.scandir()`. Forgo setting `_drv`, `_root` and `_tail_cached`, as these usually aren't needed. Use `os.DirEntry.path` to set `_str`.
1 parent 0eb52f5 commit 30f0643

File tree

2 files changed

+8
-20
lines changed

2 files changed

+8
-20
lines changed

Lib/pathlib/__init__.py

+6-20
Original file line numberDiff line numberDiff line change
@@ -584,26 +584,12 @@ def iterdir(self):
584584
The children are yielded in arbitrary order, and the
585585
special entries '.' and '..' are not included.
586586
"""
587-
return (self._make_child_relpath(name) for name in os.listdir(self))
588-
589-
590-
def _make_child_relpath(self, name):
591-
if not name:
592-
return self
593-
path_str = str(self)
594-
tail = self._tail
595-
if tail:
596-
path_str = f'{path_str}{self.parser.sep}{name}'
597-
elif path_str != '.':
598-
path_str = f'{path_str}{name}'
599-
else:
600-
path_str = name
601-
path = self.with_segments(path_str)
602-
path._str = path_str
603-
path._drv = self.drive
604-
path._root = self.root
605-
path._tail_cached = tail + [name]
606-
return path
587+
root_dir = str(self)
588+
with os.scandir(root_dir) as scandir_it:
589+
paths = [entry.path for entry in scandir_it]
590+
if root_dir == '.':
591+
paths = map(self._remove_leading_dot, paths)
592+
return map(self._from_parsed_string, paths)
607593

608594
def glob(self, pattern, *, case_sensitive=None, recurse_symlinks=False):
609595
"""Iterate over this subtree and yield all existing files (of any
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Speed up :meth:`pathlib.Path.iterdir` by using :func:`os.scandir`
2+
internally.

0 commit comments

Comments
 (0)