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.
........
diff --git a/Python/_warnings.c b/Python/_warnings.c
index 6cc493b..23223fa 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -280,6 +280,11 @@
     PyObject *item = Py_None;
     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) {
@@ -303,6 +308,8 @@
     else {
         text = message;
         message = PyObject_CallFunction(category, "O", message);
+        if (message == NULL)
+            goto cleanup;
     }
 
     lineno_obj = PyLong_FromLong(lineno);
@@ -314,7 +321,7 @@
     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 @@
        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 @@
         }
         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 @@
     Py_XDECREF(text);
     Py_XDECREF(lineno_obj);
     Py_DECREF(module);
-    Py_DECREF(message);
+    Py_XDECREF(message);
     return result;  /* Py_None or NULL. */
 }