-
-
Notifications
You must be signed in to change notification settings - Fork 33.9k
bpo-46303: Don't define _Py_stat() and _Py_wstat() on Windows #30539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| static int | ||
| file_exists(PyObject *path) | ||
| { | ||
| wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); | ||
| if (wpath == NULL) { | ||
| return -2; | ||
| } | ||
|
|
||
| DWORD attr = GetFileAttributesW(wpath); | ||
| int res = (attr != INVALID_FILE_ATTRIBUTES); | ||
|
|
||
| PyMem_Free(wpath); | ||
| return res; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GetFileAttributesW() doesn't follow a reparse point, such as a symlink, in the final component of the path. If tcl_library_path is the path of a symlink, checking existence of the target requires CreateFileW(wpath, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL). If the call succeeds, i.e. the call doesn't return INVALID_HANDLE_VALUE, the target exists and is accessible; close the handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the suggested implementation:
static int
file_exists(PyObject *path)
{
wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL);
if (wpath == NULL) {
return -2;
}
HANDLE hfile = CreateFileW(wpath, 0, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hfile != INVALID_HANDLE_VALUE) {
CloseHandle(hfile);
}
PyMem_Free(wpath);
return (hfile == INVALID_HANDLE_VALUE) ? -1 : 0;
}
This returns -1 when the file doesn't exist, since file_exists() replaces _Py_stat().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't expect that checking if a file exists would be so "complicated" :-) I'm waiting for @pacampbell to see if further changes are needed. Maybe this PR is not needed to build Python with clang.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The GetFileAttributesW() call is like checking for existence with lstat() instead of stat(). That's probably good enough for tcl_library_path. Python's r"tcl\tclX.Y" is installed as a normal directory. However, I don't think the CreateFileW() call is complicated, and it makes file_exists() generally correct.
For the current implementation, the use of res == -1 in _get_tcl_lib_path() is wrong. The current implementation returns 1 if the file exists and 0 if it doesn't exist. This has to be fixed even if you keep the GetFileAttributesW() call.
|
https://bugs.python.org/issue46303#msg410377 is now fixed, this change is not needed. |
https://bugs.python.org/issue46303