@@ -46,12 +46,35 @@ def abs_path_for_dynamic_library(handle: int) -> str:
46
46
47
47
Raises:
48
48
OSError: If GetModuleFileNameW fails
49
+ RuntimeError: If the required path length is unreasonably long
49
50
"""
50
- buf = ctypes .create_unicode_buffer (260 )
51
- n_chars = ctypes .windll .kernel32 .GetModuleFileNameW (ctypes .wintypes .HMODULE (handle ), buf , len (buf ))
52
- if n_chars == 0 :
53
- raise OSError ("GetModuleFileNameW failed" )
54
- return buf .value
51
+ MAX_ITERATIONS = 10 # Allows for extremely long paths (up to ~266,000 chars)
52
+ buf_size = 260 # Start with traditional MAX_PATH
53
+
54
+ for _ in range (MAX_ITERATIONS ):
55
+ buf = ctypes .create_unicode_buffer (buf_size )
56
+ n_chars = ctypes .windll .kernel32 .GetModuleFileNameW (ctypes .wintypes .HMODULE (handle ), buf , buf_size )
57
+
58
+ if n_chars == 0 :
59
+ raise OSError (
60
+ "GetModuleFileNameW failed. Long paths may require enabling the "
61
+ "Windows 10+ long path registry setting. See: "
62
+ "https://docs.python.org/3/using/windows.html#removing-the-max-path-limitation"
63
+ )
64
+ if n_chars < buf_size - 1 :
65
+ return buf .value
66
+
67
+ buf_size *= 2 # Double the buffer size and try again
68
+
69
+ raise RuntimeError (
70
+ f"Failed to retrieve the full path after { MAX_ITERATIONS } attempts "
71
+ f"(final buffer size: { buf_size } characters). "
72
+ "This may indicate:\n "
73
+ " 1. An extremely long path requiring Windows long path support, or\n "
74
+ " 2. An invalid or corrupt library handle, or\n "
75
+ " 3. An unexpected system error.\n "
76
+ "See: https://docs.python.org/3/using/windows.html#removing-the-max-path-limitation"
77
+ )
55
78
56
79
57
80
def check_if_already_loaded_from_elsewhere (libname : str ) -> Optional [LoadedDL ]:
0 commit comments