Skip to content

Commit a82baed

Browse files
authored
bpo-45615: Add missing test for printing traceback for non-exception. Fix traceback.py (GH-30091)
1 parent a09bc3a commit a82baed

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

Lib/test/test_traceback.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,22 @@ def test_exception_group_deep_recursion_traceback(self):
10601060
self.assertIn('ExceptionGroup', output)
10611061
self.assertLessEqual(output.count('ExceptionGroup'), LIMIT)
10621062

1063+
@cpython_only
1064+
def test_print_exception_bad_type_capi(self):
1065+
from _testcapi import exception_print
1066+
with captured_output("stderr") as stderr:
1067+
exception_print(42)
1068+
self.assertEqual(
1069+
stderr.getvalue(),
1070+
('TypeError: print_exception(): '
1071+
'Exception expected for value, int found\n')
1072+
)
1073+
1074+
def test_print_exception_bad_type_python(self):
1075+
msg = "Exception expected for value, int found"
1076+
with self.assertRaisesRegex(TypeError, msg):
1077+
traceback.print_exception(42)
1078+
10631079

10641080
cause_message = (
10651081
"\nThe above exception was the direct cause "

Lib/traceback.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ def _parse_value_tb(exc, value, tb):
9898
raise ValueError("Both or neither of value and tb must be given")
9999
if value is tb is _sentinel:
100100
if exc is not None:
101-
return exc, exc.__traceback__
101+
if isinstance(exc, BaseException):
102+
return exc, exc.__traceback__
103+
104+
raise TypeError(f'Exception expected for value, '
105+
f'{type(exc).__name__} found')
102106
else:
103107
return None, None
104108
return value, tb
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Functions in the :mod:`traceback` module raise :exc:`TypeError` rather than :exc:`AttributeError` when an exception argument is not of type :exc:`BaseException`.

Modules/_testcapimodule.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3513,17 +3513,17 @@ static PyObject *
35133513
exception_print(PyObject *self, PyObject *args)
35143514
{
35153515
PyObject *value;
3516-
PyObject *tb;
3516+
PyObject *tb = NULL;
35173517

35183518
if (!PyArg_ParseTuple(args, "O:exception_print",
3519-
&value))
3520-
return NULL;
3521-
if (!PyExceptionInstance_Check(value)) {
3522-
PyErr_Format(PyExc_TypeError, "an exception instance is required");
3519+
&value)) {
35233520
return NULL;
35243521
}
35253522

3526-
tb = PyException_GetTraceback(value);
3523+
if (PyExceptionInstance_Check(value)) {
3524+
tb = PyException_GetTraceback(value);
3525+
}
3526+
35273527
PyErr_Display((PyObject *) Py_TYPE(value), value, tb);
35283528
Py_XDECREF(tb);
35293529

0 commit comments

Comments
 (0)