Index: Python/_warnings.c =================================================================== --- Python/_warnings.c (revision 66997) +++ Python/_warnings.c (working copy) @@ -603,14 +603,33 @@ static PyObject * do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level) { - PyObject *filename, *module, *registry, *res; + PyObject *filename, *module, *registry, *res, *func; int lineno; if (!setup_context(stack_level, &filename, &lineno, &module, ®istry)) return NULL; - res = warn_explicit(category, message, filename, lineno, module, registry, - NULL); + func = get_warnings_attr("warn_explicit"); + if (func == NULL) { + if (PyErr_Occurred()) + return NULL; + res = warn_explicit(category, message, filename, lineno, module, registry, + NULL); + } + else { + PyObject *lineno_obj; + lineno_obj = PyInt_FromLong(lineno); + if (lineno_obj == NULL) { + Py_DECREF(filename); + Py_DECREF(registry); + Py_DECREF(module); + return NULL; + } + res = PyObject_CallFunctionObjArgs(func, message, category, filename, lineno_obj, + module, registry, NULL); + Py_DECREF(lineno_obj); + Py_DECREF(func); + } Py_DECREF(filename); Py_DECREF(registry); Py_DECREF(module); Index: Lib/test/test_warnings.py =================================================================== --- Lib/test/test_warnings.py (revision 66997) +++ Lib/test/test_warnings.py (working copy) @@ -60,10 +60,12 @@ # The 'warnings' module must be explicitly set so that the proper # interaction between _warnings and 'warnings' can be controlled. sys.modules['warnings'] = self.module + self.save_warn_explicit = self.module.warn_explicit super(BaseTest, self).setUp() def tearDown(self): sys.modules['warnings'] = original_warnings + self.module.warn_explicit = self.save_warn_explicit super(BaseTest, self).tearDown() @@ -424,6 +426,14 @@ result = stream.getvalue() self.failUnless(text in result) + def test_replace_warn_explicit(self): + self.called = False + def my_warn_explicit(*args): + self.called = True + self.module.warn_explicit = my_warn_explicit + self.module.warn("foo") + self.assertTrue(self.called) + def test_showwarning_not_callable(self): self.module.filterwarnings("always", category=UserWarning) old_showwarning = self.module.showwarning