Eryk Sun <eryk...@gmail.com> added the comment:

> For REMOVE_BOTH, I don't see the need of calling GetFileAttributes

I was thinking that the NtQueryAttributesFile() system call is relatively cheap 
compared to a full open, especially if the attributes of a remote file are 
cached locally. However, on second thought, it's probably not. An open can fail 
as soon as it knows that there's a file/directory type mismatch. This should be 
able to take advantage of a local attribute cache instead of incurring network 
latency.

> so I think there's no reason to combine it with the other two.

REMOVE_DIR can be separate, for the current behavior. But I wanted all modes 
handled in one function in case later on we decide to fix os.rmdir() in 
Windows. It allows deleting a directory symlink. Note that the os.lstat() 
result reports a directory symlink as an S_IFLNK file, not S_IFDIR, so the 
os.rmdir() behavior is internally inconsistent. This could be corrected by 
forcing the REMOVE_DIR mode to raise NotADirectoryError. For example:

        } else { // mode != REMOVE_BOTH

            WIN32_FIND_DATAW data;
            BOOL isDir = FALSE;
            BOOL isLnk = FALSE;

            HANDLE hFind = FindFirstFileW(path->wide, &data);
            if (hFind != INVALID_HANDLE_VALUE) {
                FindClose(hFind);
                isDir = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
                if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
                    if (mode == REMOVE_DIR) {
                        isLnk = data.dwReserved0 == IO_REPARSE_TAG_SYMLINK;
                    } else {
                        isLnk = IsReparseTagNameSurrogate(data.dwReserved0);
                    }
                }
            }

            if ((mode == REMOVE_DIR) && (isDir && isLnk)) {
                SetLastError(ERROR_DIRECTORY); // POSIX ENOTDIR
            } else if ((mode == REMOVE_DIR) || (isDir && isLnk)) {
                success = RemoveDirectoryW(path->wide);
            } else {
                success = DeleteFileW(path->wide);
            }
        }

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue46791>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to