summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_atexit.py19
-rw-r--r--Misc/NEWS3
-rw-r--r--Python/pythonrun.c10
3 files changed, 32 insertions, 0 deletions
diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py
index 3e25236..b641015 100644
--- a/Lib/test/test_atexit.py
+++ b/Lib/test/test_atexit.py
@@ -77,6 +77,25 @@ class GeneralTest(unittest.TestCase):
self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs)
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):
a = [0]
def inc():
diff --git a/Misc/NEWS b/Misc/NEWS
index f185b17..a56339c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -42,6 +42,9 @@ Core and Builtins
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
``codecs.decode``.
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index c2ca563..06f30b0 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1919,6 +1919,16 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
{
PyObject *seen;
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) {
/* pass */
}