Commit 5392cb22 authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #18776: atexit callbacks now display their full traceback when they raise an exception.

parent eafc59ae
...@@ -74,6 +74,25 @@ class TestCase(unittest.TestCase): ...@@ -74,6 +74,25 @@ class TestCase(unittest.TestCase):
self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs) self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs)
self.assertIn("ZeroDivisionError", self.stream.getvalue()) self.assertIn("ZeroDivisionError", self.stream.getvalue())
def test_print_tracebacks(self):
# Issue #18776: the tracebacks should be printed when errors occur.
def f():
1/0 # one
def g():
1/0 # two
def h():
1/0 # three
atexit.register(f)
atexit.register(g)
atexit.register(h)
self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs)
stderr = self.stream.getvalue()
self.assertEqual(stderr.count("ZeroDivisionError"), 3)
self.assertIn("# one", stderr)
self.assertIn("# two", stderr)
self.assertIn("# three", stderr)
def test_stress(self): def test_stress(self):
a = [0] a = [0]
def inc(): def inc():
......
...@@ -76,6 +76,9 @@ Core and Builtins ...@@ -76,6 +76,9 @@ Core and Builtins
Library Library
------- -------
- Issue #18776: atexit callbacks now display their full traceback when they
raise an exception.
- Issue #17827: Add the missing documentation for ``codecs.encode`` and - Issue #17827: Add the missing documentation for ``codecs.encode`` and
``codecs.decode``. ``codecs.decode``.
......
...@@ -1880,6 +1880,16 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) ...@@ -1880,6 +1880,16 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
{ {
PyObject *seen; PyObject *seen;
PyObject *f = PySys_GetObject("stderr"); PyObject *f = PySys_GetObject("stderr");
if (PyExceptionInstance_Check(value)
&& tb != NULL && PyTraceBack_Check(tb)) {
/* Put the traceback on the exception, otherwise it won't get
displayed. See issue #18776. */
PyObject *cur_tb = PyException_GetTraceback(value);
if (cur_tb == NULL)
PyException_SetTraceback(value, tb);
else
Py_DECREF(cur_tb);
}
if (f == Py_None) { if (f == Py_None) {
/* pass */ /* pass */
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment