Merged revisions 70965 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r70965 | brett.cannon | 2009-04-01 11:03:59 -0700 (Wed, 01 Apr 2009) | 5 lines

  _warnings was importing itself to get an attribute. That's bad if warnings gets
  called in a thread that was spawned by an import itself.

  Last part to close #1665206.
........
This commit is contained in:
Brett Cannon 2009-04-01 18:13:07 +00:00
parent 86fe876fb5
commit 0759dd66c5
3 changed files with 67 additions and 16 deletions

View File

@ -423,6 +423,41 @@ class _WarningsTests(BaseTest):
finally: finally:
self.module.onceregistry = original_registry self.module.onceregistry = original_registry
def test_default_action(self):
# Replacing or removing defaultaction should be okay.
message = UserWarning("defaultaction test")
original = self.module.defaultaction
try:
with original_warnings.catch_warnings(record=True,
module=self.module) as w:
self.module.resetwarnings()
registry = {}
self.module.warn_explicit(message, UserWarning, "<test>", 42,
registry=registry)
self.assertEqual(w[-1].message, message)
self.assertEqual(len(w), 1)
self.assertEqual(len(registry), 1)
del w[:]
# Test removal.
del self.module.defaultaction
__warningregistry__ = {}
registry = {}
self.module.warn_explicit(message, UserWarning, "<test>", 43,
registry=registry)
self.assertEqual(w[-1].message, message)
self.assertEqual(len(w), 1)
self.assertEqual(len(registry), 1)
del w[:]
# Test setting.
self.module.defaultaction = "ignore"
__warningregistry__ = {}
registry = {}
self.module.warn_explicit(message, UserWarning, "<test>", 44,
registry=registry)
self.assertEqual(len(w), 0)
finally:
self.module.defaultaction = original
def test_showwarning_missing(self): def test_showwarning_missing(self):
# Test that showwarning() missing is okay. # Test that showwarning() missing is okay.
text = 'del showwarning test' text = 'del showwarning test'

View File

@ -12,6 +12,8 @@ What's New in Python 3.1 alpha 2?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #1665206: Remove the last eager import in _warnings.c and make it lazy.
- Fix a segfault when running test_exceptions with coverage, caused by - Fix a segfault when running test_exceptions with coverage, caused by
insufficient checks in accessors of Exception.__context__. insufficient checks in accessors of Exception.__context__.

View File

@ -2,7 +2,6 @@
#include "frameobject.h" #include "frameobject.h"
#define MODULE_NAME "_warnings" #define MODULE_NAME "_warnings"
#define DEFAULT_ACTION_NAME "default_action"
PyDoc_STRVAR(warnings__doc__, PyDoc_STRVAR(warnings__doc__,
MODULE_NAME " provides basic warning filtering support.\n" MODULE_NAME " provides basic warning filtering support.\n"
@ -12,6 +11,7 @@ MODULE_NAME " provides basic warning filtering support.\n"
get_warnings_attr() will reset these variables accordingly. */ get_warnings_attr() will reset these variables accordingly. */
static PyObject *_filters; /* List */ static PyObject *_filters; /* List */
static PyObject *_once_registry; /* Dict */ static PyObject *_once_registry; /* Dict */
static PyObject *_default_action; /* String */
static int static int
@ -78,12 +78,31 @@ get_once_registry(void)
} }
static PyObject *
get_default_action(void)
{
PyObject *default_action;
default_action = get_warnings_attr("defaultaction");
if (default_action == NULL) {
if (PyErr_Occurred()) {
return NULL;
}
return _default_action;
}
Py_DECREF(_default_action);
_default_action = default_action;
return default_action;
}
/* The item is a borrowed reference. */ /* The item is a borrowed reference. */
static const char * static const char *
get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
PyObject *module, PyObject **item) PyObject *module, PyObject **item)
{ {
PyObject *action, *m, *d; PyObject *action;
Py_ssize_t i; Py_ssize_t i;
PyObject *warnings_filters; PyObject *warnings_filters;
@ -135,22 +154,17 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno,
return _PyUnicode_AsString(action); return _PyUnicode_AsString(action);
} }
m = PyImport_ImportModule(MODULE_NAME); action = get_default_action();
if (m == NULL) if (action != NULL) {
return NULL;
d = PyModule_GetDict(m);
Py_DECREF(m);
if (d == NULL)
return NULL;
action = PyDict_GetItemString(d, DEFAULT_ACTION_NAME);
if (action != NULL)
return _PyUnicode_AsString(action); return _PyUnicode_AsString(action);
}
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
MODULE_NAME "." DEFAULT_ACTION_NAME " not found"); MODULE_NAME ".defaultaction not found");
return NULL; return NULL;
} }
static int static int
already_warned(PyObject *registry, PyObject *key, int should_set) already_warned(PyObject *registry, PyObject *key, int should_set)
{ {
@ -874,7 +888,7 @@ static struct PyModuleDef warningsmodule = {
PyMODINIT_FUNC PyMODINIT_FUNC
_PyWarnings_Init(void) _PyWarnings_Init(void)
{ {
PyObject *m, *default_action; PyObject *m;
m = PyModule_Create(&warningsmodule); m = PyModule_Create(&warningsmodule);
if (m == NULL) if (m == NULL)
@ -894,10 +908,10 @@ _PyWarnings_Init(void)
if (PyModule_AddObject(m, "once_registry", _once_registry) < 0) if (PyModule_AddObject(m, "once_registry", _once_registry) < 0)
return NULL; return NULL;
default_action = PyUnicode_InternFromString("default"); _default_action = PyUnicode_FromString("default");
if (default_action == NULL) if (_default_action == NULL)
return NULL; return NULL;
if (PyModule_AddObject(m, DEFAULT_ACTION_NAME, default_action) < 0) if (PyModule_AddObject(m, "default_action", _default_action) < 0)
return NULL; return NULL;
return m; return m;
} }