Fix bug 683658 - PyErr_Warn may cause import deadlock.

This commit is contained in:
Mark Hammond 2003-02-19 00:33:33 +00:00
parent 4ccf3e14f0
commit a43fd0c899
3 changed files with 19 additions and 6 deletions

View file

@ -1,6 +1,10 @@
"""Python part of the warnings subsystem.""" """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 sys, re, types
import linecache
__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
"resetwarnings"] "resetwarnings"]
@ -114,7 +118,6 @@ def showwarning(message, category, filename, lineno, file=None):
def formatwarning(message, category, filename, lineno): def formatwarning(message, category, filename, lineno):
"""Function to format a warning the standard way.""" """Function to format a warning the standard way."""
import linecache
s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
line = linecache.getline(filename, lineno).strip() line = linecache.getline(filename, lineno).strip()
if line: if line:

View file

@ -600,18 +600,17 @@ PyErr_WriteUnraisable(PyObject *obj)
Py_XDECREF(tb); Py_XDECREF(tb);
} }
extern PyObject *PyModule_WarningsModule;
/* Function to issue a warning message; may raise an exception. */ /* Function to issue a warning message; may raise an exception. */
int int
PyErr_Warn(PyObject *category, char *message) PyErr_Warn(PyObject *category, char *message)
{ {
PyObject *mod, *dict, *func = NULL; PyObject *dict, *func = NULL;
mod = PyImport_ImportModule("warnings"); if (PyModule_WarningsModule != NULL) {
if (mod != NULL) { dict = PyModule_GetDict(PyModule_WarningsModule);
dict = PyModule_GetDict(mod);
func = PyDict_GetItemString(dict, "warn"); func = PyDict_GetItemString(dict, "warn");
Py_DECREF(mod);
} }
if (func == NULL) { if (func == NULL) {
PySys_WriteStderr("warning: %s\n", message); PySys_WriteStderr("warning: %s\n", message);

View file

@ -60,6 +60,11 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
true divisions (which they will be in 2.3). */ true divisions (which they will be in 2.3). */
int _Py_QnewFlag = 0; 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; static int initialized = 0;
/* API to access the initialized flag -- useful for esoteric use */ /* API to access the initialized flag -- useful for esoteric use */
@ -169,6 +174,8 @@ Py_Initialize(void)
_PyImportHooks_Init(); _PyImportHooks_Init();
PyModule_WarningsModule = PyImport_ImportModule("warnings");
initsigs(); /* Signal handling stuff, including initintr() */ initsigs(); /* Signal handling stuff, including initintr() */
initmain(); /* Module __main__ */ initmain(); /* Module __main__ */
@ -225,6 +232,10 @@ Py_Finalize(void)
/* Cleanup Codec registry */ /* Cleanup Codec registry */
_PyCodecRegistry_Fini(); _PyCodecRegistry_Fini();
/* drop module references we saved */
Py_XDECREF(PyModule_WarningsModule);
PyModule_WarningsModule = NULL;
/* Destroy all modules */ /* Destroy all modules */
PyImport_Cleanup(); PyImport_Cleanup();