diff -r c33596e6f723 Lib/test/test_warnings.py --- a/Lib/test/test_warnings.py Sat Apr 16 23:14:40 2011 +0300 +++ b/Lib/test/test_warnings.py Sun Apr 17 13:10:13 2011 +0200 @@ -519,6 +519,19 @@ finally: self.module.showwarning = old_showwarning + def test_showwarning_from_c(self): + #Issue #10271: test we can override showarning() with a PyCFunction + from _testcapi import showwarning_from_c + with original_warnings.catch_warnings(module=self.module): + self.module.filterwarnings("always", category=UserWarning) + old_showwarning = self.module.showwarning + self.module.showwarning = showwarning_from_c + try: + self.assertRaisesRegex(Exception, "DON'T PANIC", + self.module.warn, "Warning!") + finally: + self.module.showwarning = old_showwarning + def test_show_warning_output(self): # With showarning() missing, make sure that output is okay. text = 'test show_warning' diff -r c33596e6f723 Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Sat Apr 16 23:14:40 2011 +0300 +++ b/Modules/_testcapimodule.c Sun Apr 17 13:10:13 2011 +0200 @@ -2246,6 +2246,27 @@ return NULL; } +/* Issue #10271: test we can override warnings.showwarning() with a PyCFunction. + Run via Lib/test/test_warnings.py */ +static PyObject * +showwarning_from_c(PyObject *self, PyObject *args) +{ + PyObject *message, *category, *filename, *lineno; + PyObject *tmp = NULL; + + if (!PyArg_ParseTuple(args, "OOOO:showwarning_from_c", + &message, &category, &filename, &lineno)) + return NULL; + tmp = PyObject_Str(message); + if (tmp && !PyUnicode_CompareWithASCIIString(tmp, "Warning!")) + PyErr_SetString(PyExc_Exception, "DON'T PANIC"); + Py_XDECREF(tmp); + if (PyErr_Occurred()) + return NULL; + else + Py_RETURN_NONE; +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, @@ -2329,6 +2350,7 @@ {"make_memoryview_from_NULL_pointer", (PyCFunction)make_memoryview_from_NULL_pointer, METH_NOARGS}, {"crash_no_current_thread", (PyCFunction)crash_no_current_thread, METH_NOARGS}, + {"showwarning_from_c", (PyCFunction)showwarning_from_c, METH_VARARGS}, {NULL, NULL} /* sentinel */ };