]> granicus.if.org Git - python/commitdiff
Fix bug 683658 - PyErr_Warn may cause import deadlock.
authorMark Hammond <mhammond@skippinet.com.au>
Wed, 19 Feb 2003 00:33:33 +0000 (00:33 +0000)
committerMark Hammond <mhammond@skippinet.com.au>
Wed, 19 Feb 2003 00:33:33 +0000 (00:33 +0000)
Lib/warnings.py
Python/errors.c
Python/pythonrun.c

index 16ae3314b845475ee953a635045e7e6b2fc58d28..bab007fd34b0b44686e674e064c5c0f55df4ff36 100644 (file)
@@ -1,6 +1,10 @@
 """Python part of the warnings subsystem."""
 
+# Note: function level imports should *not* be used
+# in this module as it may cause import lock deadlock.
+# See bug 683658.
 import sys, re, types
+import linecache
 
 __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
            "resetwarnings"]
@@ -114,7 +118,6 @@ def showwarning(message, category, filename, lineno, file=None):
 
 def formatwarning(message, category, filename, lineno):
     """Function to format a warning the standard way."""
-    import linecache
     s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
     line = linecache.getline(filename, lineno).strip()
     if line:
index e50960661e73611aec8e59cad7526a8c439bda80..d08c1afc123eed70858f5b55cb8b4582dcf67667 100644 (file)
@@ -600,18 +600,17 @@ PyErr_WriteUnraisable(PyObject *obj)
        Py_XDECREF(tb);
 }
 
+extern PyObject *PyModule_WarningsModule;
 
 /* Function to issue a warning message; may raise an exception. */
 int
 PyErr_Warn(PyObject *category, char *message)
 {
-       PyObject *mod, *dict, *func = NULL;
+       PyObject *dict, *func = NULL;
 
-       mod = PyImport_ImportModule("warnings");
-       if (mod != NULL) {
-               dict = PyModule_GetDict(mod);
+       if (PyModule_WarningsModule != NULL) {
+               dict = PyModule_GetDict(PyModule_WarningsModule);
                func = PyDict_GetItemString(dict, "warn");
-               Py_DECREF(mod);
        }
        if (func == NULL) {
                PySys_WriteStderr("warning: %s\n", message);
index 1faab509ba9d6a1afcd26eed65f726ff541f02c0..2845d2429512794e36d9acffa822184231682361 100644 (file)
@@ -60,6 +60,11 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
   true divisions (which they will be in 2.3). */
 int _Py_QnewFlag = 0;
 
+/* Reference to 'warnings' module, to avoid importing it
+   on the fly when the import lock may be held.  See 683658
+*/
+PyObject *PyModule_WarningsModule = NULL;
+
 static int initialized = 0;
 
 /* API to access the initialized flag -- useful for esoteric use */
@@ -169,6 +174,8 @@ Py_Initialize(void)
 
        _PyImportHooks_Init();
 
+       PyModule_WarningsModule = PyImport_ImportModule("warnings");
+
        initsigs(); /* Signal handling stuff, including initintr() */
 
        initmain(); /* Module __main__ */
@@ -225,6 +232,10 @@ Py_Finalize(void)
        /* Cleanup Codec registry */
        _PyCodecRegistry_Fini();
 
+       /* drop module references we saved */
+       Py_XDECREF(PyModule_WarningsModule);
+       PyModule_WarningsModule = NULL;
+
        /* Destroy all modules */
        PyImport_Cleanup();