@@ -69,9 +69,38 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
69
69
int _Py_QnewFlag = 0 ;
70
70
71
71
/* Reference to 'warnings' module, to avoid importing it
72
- on the fly when the import lock may be held. See 683658
72
+ on the fly when the import lock may be held. See 683658/771097
73
73
*/
74
- PyObject * PyModule_WarningsModule = NULL ;
74
+ static PyObject * warnings_module = NULL ;
75
+
76
+ /* Returns a borrowed reference to the 'warnings' module, or NULL.
77
+ If the module is returned, it is guaranteed to have been obtained
78
+ without acquiring the import lock
79
+ */
80
+ PyObject * PyModule_GetWarningsModule ()
81
+ {
82
+ PyObject * typ , * val , * tb ;
83
+ PyObject * all_modules ;
84
+ /* If we managed to get the module at init time, just use it */
85
+ if (warnings_module )
86
+ return warnings_module ;
87
+ /* If it wasn't available at init time, it may be available
88
+ now in sys.modules (common scenario is frozen apps: import
89
+ at init time fails, but the frozen init code sets up sys.path
90
+ correctly, then does an implicit import of warnings for us
91
+ */
92
+ /* Save and restore any exceptions */
93
+ PyErr_Fetch (& typ , & val , & tb );
94
+
95
+ all_modules = PySys_GetObject ("__modules__" );
96
+ if (all_modules ) {
97
+ warnings_module = PyDict_GetItemString (all_modules , "warnings" );
98
+ /* We keep a ref in the global */
99
+ Py_XINCREF (warnings_module );
100
+ }
101
+ PyErr_Restore (typ , val , tb );
102
+ return warnings_module ;
103
+ }
75
104
76
105
static int initialized = 0 ;
77
106
@@ -190,7 +219,9 @@ Py_Initialize(void)
190
219
_PyGILState_Init (interp , tstate );
191
220
#endif /* WITH_THREAD */
192
221
193
- PyModule_WarningsModule = PyImport_ImportModule ("warnings" );
222
+ warnings_module = PyImport_ImportModule ("warnings" );
223
+ if (!warnings_module )
224
+ PyErr_Clear ();
194
225
195
226
#if defined(Py_USING_UNICODE ) && defined(HAVE_LANGINFO_H ) && defined(CODESET )
196
227
/* On Unix, set the file system encoding according to the
@@ -262,8 +293,8 @@ Py_Finalize(void)
262
293
PyOS_FiniInterrupts ();
263
294
264
295
/* drop module references we saved */
265
- Py_XDECREF (PyModule_WarningsModule );
266
- PyModule_WarningsModule = NULL ;
296
+ Py_XDECREF (warnings_module );
297
+ warnings_module = NULL ;
267
298
268
299
/* Collect garbage. This may call finalizers; it's nice to call these
269
300
before all modules are destroyed. */
0 commit comments