@@ -15,6 +15,9 @@ extern "C" {
1515
1616
1717_PyPathConfig _Py_path_config = _PyPathConfig_INIT ;
18+ #ifdef MS_WINDOWS
19+ wchar_t * _Py_dll_path = NULL ;
20+ #endif
1821
1922
2023static int
@@ -51,9 +54,6 @@ pathconfig_clear(_PyPathConfig *config)
5154 CLEAR (config -> prefix );
5255 CLEAR (config -> program_full_path );
5356 CLEAR (config -> exec_prefix );
54- #ifdef MS_WINDOWS
55- CLEAR (config -> dll_path );
56- #endif
5757 CLEAR (config -> module_search_path );
5858 CLEAR (config -> home );
5959 CLEAR (config -> program_name );
@@ -114,54 +114,17 @@ pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config)
114114}
115115
116116
117- PyStatus
118- _PyPathConfig_SetGlobal (const _PyPathConfig * config )
119- {
120- PyStatus status ;
121- _PyPathConfig new_config = _PyPathConfig_INIT ;
122-
123- PyMemAllocatorEx old_alloc ;
124- _PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
125-
126- #define COPY_ATTR (ATTR ) \
127- do { \
128- if (copy_wstr(&new_config.ATTR, config->ATTR) < 0) { \
129- pathconfig_clear(&new_config); \
130- status = _PyStatus_NO_MEMORY(); \
131- goto done; \
132- } \
133- } while (0)
134-
135- COPY_ATTR (program_full_path );
136- COPY_ATTR (prefix );
137- COPY_ATTR (exec_prefix );
138- #ifdef MS_WINDOWS
139- COPY_ATTR (dll_path );
140- #endif
141- COPY_ATTR (module_search_path );
142- COPY_ATTR (program_name );
143- COPY_ATTR (home );
144- COPY_ATTR (base_executable );
145-
146- pathconfig_clear (& _Py_path_config );
147- /* Steal new_config strings; don't clear new_config */
148- _Py_path_config = new_config ;
149-
150- status = _PyStatus_OK ();
151-
152- done :
153- PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
154- return status ;
155- }
156-
157-
158117void
159118_PyPathConfig_ClearGlobal (void )
160119{
161120 PyMemAllocatorEx old_alloc ;
162121 _PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
163122
164123 pathconfig_clear (& _Py_path_config );
124+ #ifdef MS_WINDOWS
125+ PyMem_RawFree (_Py_dll_path );
126+ _Py_dll_path = NULL ;
127+ #endif
165128
166129 PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
167130}
@@ -200,12 +163,36 @@ _PyWideStringList_Join(const PyWideStringList *list, wchar_t sep)
200163
201164/* Set the global path configuration from config. */
202165PyStatus
203- _PyConfig_SetPathConfig ( const PyConfig * config )
166+ _PyPathConfig_Init ( void )
204167{
168+ #ifdef MS_WINDOWS
169+ if (_Py_dll_path == NULL ) {
170+ /* Already set: nothing to do */
171+ return _PyStatus_OK ();
172+ }
173+
205174 PyMemAllocatorEx old_alloc ;
206175 _PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
207176
177+ _Py_dll_path = _Py_GetDLLPath ();
178+
179+ PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
180+
181+ if (_Py_dll_path == NULL ) {
182+ return _PyStatus_NO_MEMORY ();
183+ }
184+ #endif
185+ return _PyStatus_OK ();
186+ }
187+
188+
189+ static PyStatus
190+ pathconfig_global_init_from_config (const PyConfig * config )
191+ {
208192 PyStatus status ;
193+ PyMemAllocatorEx old_alloc ;
194+ _PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
195+
209196 _PyPathConfig pathconfig = _PyPathConfig_INIT ;
210197
211198 pathconfig .module_search_path = _PyWideStringList_Join (& config -> module_search_paths , DELIM );
@@ -222,12 +209,6 @@ _PyConfig_SetPathConfig(const PyConfig *config)
222209 if (copy_wstr (& pathconfig .exec_prefix , config -> exec_prefix ) < 0 ) {
223210 goto no_memory ;
224211 }
225- #ifdef MS_WINDOWS
226- pathconfig .dll_path = _Py_GetDLLPath ();
227- if (pathconfig .dll_path == NULL ) {
228- goto no_memory ;
229- }
230- #endif
231212 if (copy_wstr (& pathconfig .program_name , config -> program_name ) < 0 ) {
232213 goto no_memory ;
233214 }
@@ -238,19 +219,18 @@ _PyConfig_SetPathConfig(const PyConfig *config)
238219 goto no_memory ;
239220 }
240221
241- status = _PyPathConfig_SetGlobal (& pathconfig );
242- if (_PyStatus_EXCEPTION (status )) {
243- goto done ;
244- }
222+ pathconfig_clear (& _Py_path_config );
223+ /* Steal new_config strings; don't clear new_config */
224+ _Py_path_config = pathconfig ;
245225
246226 status = _PyStatus_OK ();
247227 goto done ;
248228
249229no_memory :
230+ pathconfig_clear (& pathconfig );
250231 status = _PyStatus_NO_MEMORY ();
251232
252233done :
253- pathconfig_clear (& pathconfig );
254234 PyMem_SetAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
255235 return status ;
256236}
@@ -402,12 +382,17 @@ _PyConfig_InitPathConfig(PyConfig *config)
402382static void
403383pathconfig_global_init (void )
404384{
385+ /* Initialize _Py_dll_path if needed */
386+ PyStatus status = _PyPathConfig_Init ();
387+ if (_PyStatus_EXCEPTION (status )) {
388+ Py_ExitStatusException (status );
389+ }
390+
405391 if (_Py_path_config .module_search_path != NULL ) {
406392 /* Already initialized */
407393 return ;
408394 }
409395
410- PyStatus status ;
411396 PyConfig config ;
412397 _PyConfig_InitCompatConfig (& config );
413398
@@ -416,7 +401,7 @@ pathconfig_global_init(void)
416401 goto error ;
417402 }
418403
419- status = _PyConfig_SetPathConfig (& config );
404+ status = pathconfig_global_init_from_config (& config );
420405 if (_PyStatus_EXCEPTION (status )) {
421406 goto error ;
422407 }
@@ -450,10 +435,6 @@ Py_SetPath(const wchar_t *path)
450435 alloc_error |= (new_config .prefix == NULL );
451436 new_config .exec_prefix = _PyMem_RawWcsdup (L"" );
452437 alloc_error |= (new_config .exec_prefix == NULL );
453- #ifdef MS_WINDOWS
454- new_config .dll_path = _Py_GetDLLPath ();
455- alloc_error |= (new_config .dll_path == NULL );
456- #endif
457438 new_config .module_search_path = _PyMem_RawWcsdup (path );
458439 alloc_error |= (new_config .module_search_path == NULL );
459440
0 commit comments