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

Skip to content

Commit 06ddd35

Browse files
committed
Issue #25911: Backport os._DummyDirEntry fixes
* Fix test_os.BytesWalkTests on Windows * Mimick better the reference os.DirEntry on Windows * _DummyDirEntry now caches os.stat() result * _DummyDirEntry constructor now tries to get os.stat() * Fix os._DummyDirEntry.is_symlink(), don't follow symbolic links: use os.stat(path, follow_symlinks=False).
1 parent 8ba2083 commit 06ddd35

1 file changed

Lines changed: 36 additions & 2 deletions

File tree

Lib/os.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,13 +425,47 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
425425
yield top, dirs, nondirs
426426

427427
class _DummyDirEntry:
428+
"""Dummy implementation of DirEntry
429+
430+
Only used internally by os.walk(bytes). Since os.walk() doesn't need the
431+
follow_symlinks parameter: don't implement it, always follow symbolic
432+
links.
433+
"""
434+
428435
def __init__(self, dir, name):
429436
self.name = name
430437
self.path = path.join(dir, name)
438+
# Mimick FindFirstFile/FindNextFile: we should get file attributes
439+
# while iterating on a directory
440+
self._stat = None
441+
self._lstat = None
442+
try:
443+
self.stat(follow_symlinks=False)
444+
except OSError:
445+
pass
446+
447+
def stat(self, *, follow_symlinks=True):
448+
if follow_symlinks:
449+
if self._stat is None:
450+
self._stat = stat(self.path)
451+
return self._stat
452+
else:
453+
if self._lstat is None:
454+
self._lstat = stat(self.path, follow_symlinks=False)
455+
return self._lstat
456+
431457
def is_dir(self):
432-
return path.isdir(self.path)
458+
if self._lstat is not None and not self.is_symlink():
459+
# use the cache lstat
460+
stat = self.stat(follow_symlinks=False)
461+
return st.S_ISDIR(stat.st_mode)
462+
463+
stat = self.stat()
464+
return st.S_ISDIR(stat.st_mode)
465+
433466
def is_symlink(self):
434-
return path.islink(self.path)
467+
stat = self.stat(follow_symlinks=False)
468+
return st.S_ISLNK(stat.st_mode)
435469

436470
def _dummy_scandir(dir):
437471
# listdir-based implementation for bytes patches on Windows

0 commit comments

Comments
 (0)