This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients benrg, bup, eryksun
Date 2022-03-01.00:05:50
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1646093150.53.0.0337011816081.issue46791@roundup.psfhosted.org>
In-reply-to
Content
> 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);
            }
        }
History
Date User Action Args
2022-03-01 00:05:50eryksunsetrecipients: + eryksun, benrg, bup
2022-03-01 00:05:50eryksunsetmessageid: <1646093150.53.0.0337011816081.issue46791@roundup.psfhosted.org>
2022-03-01 00:05:50eryksunlinkissue46791 messages
2022-03-01 00:05:50eryksuncreate