summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_traceback.py16
-rw-r--r--Lib/traceback.py6
-rw-r--r--Misc/NEWS.d/next/Library/2021-12-13-15-51-16.bpo-45615.hVx83Q.rst1
-rw-r--r--Modules/_testcapimodule.c12
4 files changed, 28 insertions, 7 deletions
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 97bd9ba..a0e4656 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 b244750..05f1fff 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 0000000..f8cd911
--- /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 6116365..be40d68 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);