Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 461b73d

Browse files
committed
GH-113225: Speed up pathlib.Path.iterdir() and glob()
Use `os.DirEntry.path` as the string representation of child paths, unless the parent path is empty, in which case we use the entry `name`.
1 parent 2f0ec7f commit 461b73d

3 files changed

Lines changed: 18 additions & 6 deletions

File tree

Lib/pathlib/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,18 @@ def iterdir(self):
272272
The children are yielded in arbitrary order, and the
273273
special entries '.' and '..' are not included.
274274
"""
275-
return (self._make_child_relpath(name) for name in os.listdir(self))
275+
with os.scandir(self) as entries:
276+
return iter([self._make_child_entry(entry) for entry in entries])
276277

277278
def _scandir(self):
278279
return os.scandir(self)
279280

281+
def _make_child_entry(self, entry):
282+
# Transform an entry yielded from _scandir() into a path object.
283+
path = self.with_segments(entry.path)
284+
path._str = entry.name if str(self) == '.' else entry.path
285+
return path
286+
280287
def absolute(self):
281288
"""Return an absolute version of this path
282289
No normalization or symlink resolution is performed.

Lib/pathlib/_abc.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,8 @@ def _select_children(parent_paths, dir_only, follow_symlinks, match):
8989
continue
9090
except OSError:
9191
continue
92-
name = entry.name
93-
if match(name):
94-
yield parent_path._make_child_relpath(name)
92+
if match(entry.name):
93+
yield parent_path._make_child_entry(entry)
9594

9695

9796
def _select_recursive(parent_paths, dir_only, follow_symlinks):
@@ -114,12 +113,12 @@ def _select_recursive(parent_paths, dir_only, follow_symlinks):
114113
for entry in entries:
115114
try:
116115
if entry.is_dir(follow_symlinks=follow_symlinks):
117-
paths.append(path._make_child_relpath(entry.name))
116+
paths.append(path._make_child_entry(entry))
118117
continue
119118
except OSError:
120119
pass
121120
if not dir_only:
122-
yield path._make_child_relpath(entry.name)
121+
yield path._make_child_entry(entry)
123122

124123

125124
def _select_unique(paths):
@@ -797,6 +796,10 @@ def _scandir(self):
797796
from contextlib import nullcontext
798797
return nullcontext(self.iterdir())
799798

799+
def _make_child_entry(self, entry):
800+
# Transform an entry yielded from _scandir() into a path object.
801+
return entry
802+
800803
def _make_child_relpath(self, name):
801804
path_str = str(self)
802805
tail = self._tail
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Speed up :meth:`pathlib.Path.iterdir` and :meth:`~pathlib.Path.glob` by
2+
using :attr:`os.DirEntry.path` where possible.

0 commit comments

Comments
 (0)