[Python-Dev] Updates to PEP 471, the os.scandir() proposal

Victor Stinner victor.stinner at gmail.com
Thu Jul 10 02:57:00 CEST 2014

Oh, since I'm proposing to add a new stat() method to DirEntry, we can
optimize it. stat() can reuse lstat() result if the file is not a
symlink. It simplifies is_dir().

New pseudo-code:
class DirEntry:
    def __init__(self, path, name, lstat=None, d_type=None):
        self.name = name
        self.full_name = os.path.join(path, name)
        # lstat is known on Windows
        self._lstat = lstat
        if lstat is not None and not stat.S_ISLNK(lstat.st_mode):
            # On Windows, stat() only calls os.stat() for symlinks
            self._stat = lstat
            self._stat = None
        # d_type is known on UNIX
        if d_type != DT_UNKNOWN:
            self._d_type = d_type
           # DT_UNKNOWN is not a very useful information :-p
           self._d_type = None

    def stat(self):
        if self._stat is None:
            self._stat = os.stat(self.full_name)
        return self._stat

    def lstat(self):
        if self._lstat is None:
            self._lstat = os.lstat(self.full_name)
            if self._stat is None and not stat.S_ISLNK(self._lstat.st_mode):
                self._stat = lstat
        return self._lstat

    def is_dir(self):
        if self._d_type is not None:
            if self._d_type == DT_DIR:
                return True
            if self._d_type != DT_LNK:
                return False
            lstat = self.lstat()
            if stat.S_ISDIR(lstat.st_mode):
                return True
        stat = self.stat()   # if lstat() was already called, stat()
will only call os.stat() for symlink
        return stat.S_ISDIR(stat.st_mode)

The extra caching rules are complex, that's why I suggest to not document them.

In short: is_dir() only needs an extra syscall for symlinks, for other
file types it does not need any syscall.


More information about the Python-Dev mailing list