Merged revisions 64549 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r64549 | brett.cannon | 2008-06-26 17:31:13 -0700 (Thu, 26 Jun 2008) | 7 lines warnings.warn_explicit() did not have the proper TypeErrors in place to prevent bus errors or SystemError being raised. As a side effect of fixing this, a bad DECREF that could be triggered when 'message' and 'category' were both None was fixed. Closes issue 3211. Thanks JP Calderone for the bug report. ........
This commit is contained in:
parent
429ef650b7
commit
db7349128f
|
@ -301,6 +301,21 @@ class WarnTests(unittest.TestCase):
|
|||
warning_tests.__name__ = module_name
|
||||
sys.argv = argv
|
||||
|
||||
def test_warn_explicit_type_errors(self):
|
||||
# warn_explicit() shoud error out gracefully if it is given objects
|
||||
# of the wrong types.
|
||||
# lineno is expected to be an integer.
|
||||
self.assertRaises(TypeError, self.module.warn_explicit,
|
||||
None, UserWarning, None, None)
|
||||
# Either 'message' needs to be an instance of Warning or 'category'
|
||||
# needs to be a subclass.
|
||||
self.assertRaises(TypeError, self.module.warn_explicit,
|
||||
None, None, None, 1)
|
||||
# 'registry' must be a dict or None.
|
||||
self.assertRaises((TypeError, AttributeError),
|
||||
self.module.warn_explicit,
|
||||
None, Warning, None, 1, registry=42)
|
||||
|
||||
|
||||
|
||||
class CWarnTests(BaseTest, WarnTests):
|
||||
|
|
|
@ -188,6 +188,7 @@ def warn(message, category=None, stacklevel=1):
|
|||
|
||||
def warn_explicit(message, category, filename, lineno,
|
||||
module=None, registry=None, module_globals=None):
|
||||
lineno = int(lineno)
|
||||
if module is None:
|
||||
module = filename or "<unknown>"
|
||||
if module[-3:].lower() == ".py":
|
||||
|
|
|
@ -27,6 +27,11 @@ What's new in Python 3.0b1?
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #3211: warnings.warn_explicit() did not guard against its 'registry'
|
||||
argument being anything other than a dict or None. Also fixed a bug in error
|
||||
handling when 'message' and 'category' were both set to None, triggering a
|
||||
bus error.
|
||||
|
||||
- Issue #3100: Corrected a crash on deallocation of a subclassed weakref which
|
||||
holds the last (strong) reference to its referent.
|
||||
|
||||
|
|
|
@ -281,6 +281,11 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
const char *action;
|
||||
int rc;
|
||||
|
||||
if (registry && !PyDict_Check(registry) && (registry != Py_None)) {
|
||||
PyErr_SetString(PyExc_TypeError, "'registry' must be a dict");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Normalize module. */
|
||||
if (module == NULL) {
|
||||
module = normalize_module(filename);
|
||||
|
@ -303,6 +308,8 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
else {
|
||||
text = message;
|
||||
message = PyObject_CallFunction(category, "O", message);
|
||||
if (message == NULL)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
lineno_obj = PyLong_FromLong(lineno);
|
||||
|
@ -314,7 +321,7 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
if (key == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if (registry != NULL) {
|
||||
if ((registry != NULL) && (registry != Py_None)) {
|
||||
rc = already_warned(registry, key, 0);
|
||||
if (rc == -1)
|
||||
goto cleanup;
|
||||
|
@ -336,12 +343,13 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
is "always". */
|
||||
rc = 0;
|
||||
if (strcmp(action, "always") != 0) {
|
||||
if (registry != NULL && PyDict_SetItem(registry, key, Py_True) < 0)
|
||||
if (registry != NULL && registry != Py_None &&
|
||||
PyDict_SetItem(registry, key, Py_True) < 0)
|
||||
goto cleanup;
|
||||
else if (strcmp(action, "ignore") == 0)
|
||||
goto return_none;
|
||||
else if (strcmp(action, "once") == 0) {
|
||||
if (registry == NULL) {
|
||||
if (registry == NULL || registry == Py_None) {
|
||||
registry = get_once_registry();
|
||||
if (registry == NULL)
|
||||
goto cleanup;
|
||||
|
@ -351,7 +359,7 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
}
|
||||
else if (strcmp(action, "module") == 0) {
|
||||
/* registry[(text, category, 0)] = 1 */
|
||||
if (registry != NULL)
|
||||
if (registry != NULL && registry != Py_None)
|
||||
rc = update_registry(registry, text, category, 0);
|
||||
}
|
||||
else if (strcmp(action, "default") != 0) {
|
||||
|
@ -435,7 +443,7 @@ warn_explicit(PyObject *category, PyObject *message,
|
|||
Py_XDECREF(text);
|
||||
Py_XDECREF(lineno_obj);
|
||||
Py_DECREF(module);
|
||||
Py_DECREF(message);
|
||||
Py_XDECREF(message);
|
||||
return result; /* Py_None or NULL. */
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue