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

This commit is contained in:
Irit Katriel 2022-01-02 09:34:03 +00:00 committed by GitHub
parent a09bc3a404
commit a82baed0e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 7 deletions

View File

@ -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 "

View File

@ -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

View File

@ -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`.

View File

@ -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);