[Python-checkins] bpo-45615: Add missing test for printing traceback for non-exception. Fix traceback.py (GH-30091)

iritkatriel webhook-mailer at python.org
Sun Jan 2 04:34:38 EST 2022


https://github.com/python/cpython/commit/a82baed0e9e61c0d8dc5c12fc08de7fc172c1a38
commit: a82baed0e9e61c0d8dc5c12fc08de7fc172c1a38
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2022-01-02T09:34:03Z
summary:

bpo-45615: Add missing test for printing traceback for non-exception. Fix traceback.py (GH-30091)

files:
A Misc/NEWS.d/next/Library/2021-12-13-15-51-16.bpo-45615.hVx83Q.rst
M Lib/test/test_traceback.py
M Lib/traceback.py
M Modules/_testcapimodule.c

diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 97bd9bae1d58e..a0e4656d3d9ea 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -1060,6 +1060,22 @@ def test_exception_group_deep_recursion_traceback(self):
         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 b244750fd016e..05f1fffef0d3b 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 0000000000000..f8cd911ea6365
--- /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 6116365b2c0f7..be40d68b40b17 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);
 



More information about the Python-checkins mailing list