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

Victor Stinner victor.stinner at gmail.com
Wed Jul 9 17:05:33 CEST 2014


2014-07-09 15:12 GMT+02:00 Ben Hoyt <benhoyt at gmail.com>:

Ok, so it means that your example grouping files per type, files and directories, is also wrong. Or at least, it behaves differently than os.walk(). You should put symbolic links to directories in the "dirs" list too.

if entry.isdir(): # isdir() checks os.lstat() dirs.append(entry) elif entry.issymlink() and os.path.isdir(entry): # isdir() checks os.stat() dirs.append(entry) else: nondirs.append(entry) Yes, good call. I believe I'm doing this wrong in the scandir.py os.walk() implementation too -- hence this open issue: https://github.com/benhoyt/scandir/issues/4

The PEP says that DirEntry should mimic pathlib.Path, so I think that DirEntry.is_dir() should work as os.path.isir(): if the entry is a symbolic link, you should follow the symlink to get the status of the linked file with os.stat().

"entry.is_dir() or (entry.is_symlink() and os.path.isdir(entry))" looks wrong: why would you have to check is_dir() and isdir()? Duplicating this check is error prone and not convinient.

Pseudo-code:

class DirEntry: def init(self, lstat=None, d_type=None): self._stat = None self._lstat = lstat self._d_type = d_type

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)
    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
    else:
        lstat = self.lstat()
        if stat.S_ISDIR(lstat.st_mode):
            return True
        if not stat.S_ISLNK(lstat.st_mode):
            return False
    stat = self.stat()
    return stat.S_ISDIR(stat.st_mode)

DirEntry would be created with lstat (Windows) or d_type (Linux) prefilled. is_dir() would only need to call os.stat() once for symbolic links.

With this code, it becomes even more obvious why is_dir() is a method and not a property ;-)

Victor



More information about the Python-Dev mailing list