mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue #18776: atexit callbacks now display their full traceback when they raise an exception.
This commit is contained in:
commit
6039db8de3
3 changed files with 32 additions and 0 deletions
|
@ -77,6 +77,25 @@ class GeneralTest(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():
|
||||||
|
|
|
@ -42,6 +42,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``.
|
||||||
|
|
||||||
|
|
|
@ -1919,6 +1919,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 */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue