From 238a0e11bb4dba6f5357d7ff7890bd6d9c3515ea Mon Sep 17 00:00:00 2001 From: Solaris-star <820622658@qq.com> Date: Tue, 1 Sep 2026 18:09:31 +0800 Subject: [PATCH] gh-126929: Retry extension loading with long Windows paths Signed-off-by: Solaris-star <820622658@qq.com> --- ...10-05-00.gh-issue-126929.long-path-dll.rst | 1 + Python/dynload_win.c | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 Misc/NEWS.d/next/Windows/2026-09-01-10-05-00.gh-issue-126929.long-path-dll.rst diff --git a/Misc/NEWS.d/next/Windows/2026-09-01-10-05-00.gh-issue-126929.long-path-dll.rst b/Misc/NEWS.d/next/Windows/2026-09-01-10-05-00.gh-issue-126929.long-path-dll.rst new file mode 100644 index 00000000000000..62cd5257c864c9 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-09-01-10-05-00.gh-issue-126929.long-path-dll.rst @@ -0,0 +1 @@ +Fix loading extension modules from long Windows paths by retrying with an extended-length path after the initial load fails and the target is confirmed to be a regular file. diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 1c2544e94160ac..77ae331eccf9d4 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -307,6 +307,36 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, hDLL = LoadLibraryExW(wpathname, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); + if (hDLL == NULL) { + DWORD attributes = GetFileAttributesW(wpathname); + if (attributes != INVALID_FILE_ATTRIBUTES && + !(attributes & FILE_ATTRIBUTE_DIRECTORY)) { + size_t path_length = wcslen(wpathname); + int is_unc = wpathname[0] == L'\\' && wpathname[1] == L'\\'; + size_t prefix_length = is_unc ? 8 : 4; + wchar_t *extended_path = PyMem_RawMalloc( + (path_length + prefix_length + 1) * sizeof(wchar_t)); + if (extended_path != NULL) { + if (is_unc) { + wcscpy_s(extended_path, path_length + prefix_length + 1, + L"\\\\?\\UNC\\"); + wcscat_s(extended_path, path_length + prefix_length + 1, + wpathname + 2); + } + else { + wcscpy_s(extended_path, path_length + prefix_length + 1, + L"\\\\?\\"); + wcscat_s(extended_path, path_length + prefix_length + 1, + wpathname); + } + hDLL = LoadLibraryExW( + extended_path, NULL, + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | + LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); + PyMem_RawFree(extended_path); + } + } + } Py_END_ALLOW_THREADS PyMem_Free(wpathname);