From a82baed0e9e61c0d8dc5c12fc08de7fc172c1a38 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sun, 2 Jan 2022 09:34:03 +0000 Subject: [PATCH] bpo-45615: Add missing test for printing traceback for non-exception. Fix traceback.py (GH-30091) --- Lib/test/test_traceback.py | 16 ++++++++++++++++ Lib/traceback.py | 6 +++++- .../2021-12-13-15-51-16.bpo-45615.hVx83Q.rst | 1 + Modules/_testcapimodule.c | 12 ++++++------ 4 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-12-13-15-51-16.bpo-45615.hVx83Q.rst diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 97bd9bae1d5..a0e4656d3d9 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -1060,6 +1060,22 @@ class TracebackFormatTests(unittest.TestCase): self.assertIn('ExceptionGroup', output) self.assertLessEqual(output.count('ExceptionGroup'), LIMIT) + @cpython_only + def test_print_exception_bad_type_capi(self): + from _testcapi import exception_print + with captured_output("stderr") as stderr: + exception_print(42) + self.assertEqual( + stderr.getvalue(), + ('TypeError: print_exception(): ' + 'Exception expected for value, int found\n') + ) + + def test_print_exception_bad_type_python(self): + msg = "Exception expected for value, int found" + with self.assertRaisesRegex(TypeError, msg): + traceback.print_exception(42) + cause_message = ( "\nThe above exception was the direct cause " diff --git a/Lib/traceback.py b/Lib/traceback.py index b244750fd01..05f1fffef0d 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -98,7 +98,11 @@ def _parse_value_tb(exc, value, tb): raise ValueError("Both or neither of value and tb must be given") if value is tb is _sentinel: if exc is not None: - return exc, exc.__traceback__ + if isinstance(exc, BaseException): + return exc, exc.__traceback__ + + raise TypeError(f'Exception expected for value, ' + f'{type(exc).__name__} found') else: return None, None return value, tb diff --git a/Misc/NEWS.d/next/Library/2021-12-13-15-51-16.bpo-45615.hVx83Q.rst b/Misc/NEWS.d/next/Library/2021-12-13-15-51-16.bpo-45615.hVx83Q.rst new file mode 100644 index 00000000000..f8cd911ea63 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-13-15-51-16.bpo-45615.hVx83Q.rst @@ -0,0 +1 @@ +Functions in the :mod:`traceback` module raise :exc:`TypeError` rather than :exc:`AttributeError` when an exception argument is not of type :exc:`BaseException`. \ No newline at end of file diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 6116365b2c0..be40d68b40b 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3513,17 +3513,17 @@ static PyObject * exception_print(PyObject *self, PyObject *args) { PyObject *value; - PyObject *tb; + PyObject *tb = NULL; if (!PyArg_ParseTuple(args, "O:exception_print", - &value)) - return NULL; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, "an exception instance is required"); + &value)) { return NULL; } - tb = PyException_GetTraceback(value); + if (PyExceptionInstance_Check(value)) { + tb = PyException_GetTraceback(value); + } + PyErr_Display((PyObject *) Py_TYPE(value), value, tb); Py_XDECREF(tb);