Skip to content

Commit 5c471f3

Browse files
authored
gh-102755: PyErr_DisplayException only in ABI >= 3.12. Tests cover PyErr_Display as well (GH-102849)
1 parent 82eb946 commit 5c471f3

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

Include/pythonrun.h

+3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ PyAPI_FUNC(PyObject *) Py_CompileString(const char *, const char *, int);
1212
PyAPI_FUNC(void) PyErr_Print(void);
1313
PyAPI_FUNC(void) PyErr_PrintEx(int);
1414
PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *);
15+
16+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000
1517
PyAPI_FUNC(void) PyErr_DisplayException(PyObject *);
18+
#endif
1619

1720

1821
/* Stuff with no proper home (yet) */

Lib/test/test_traceback.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -394,18 +394,22 @@ def get_exception(self, callable, slice_start=0, slice_end=-1):
394394

395395

396396
class CAPIExceptionFormattingMixin:
397+
LEGACY = 0
398+
397399
def get_exception(self, callable, slice_start=0, slice_end=-1):
398400
from _testcapi import exception_print
399401
try:
400402
callable()
401403
self.fail("No exception thrown.")
402404
except Exception as e:
403405
with captured_output("stderr") as tbstderr:
404-
exception_print(e)
406+
exception_print(e, self.LEGACY)
405407
return tbstderr.getvalue().splitlines()[slice_start:slice_end]
406408

407409
callable_line = get_exception.__code__.co_firstlineno + 3
408410

411+
class CAPIExceptionFormattingLegacyMixin(CAPIExceptionFormattingMixin):
412+
LEGACY = 1
409413

410414
@requires_debug_ranges()
411415
class TracebackErrorLocationCaretTestBase:
@@ -912,6 +916,16 @@ class CPythonTracebackErrorCaretTests(
912916
Same set of tests as above but with Python's internal traceback printing.
913917
"""
914918

919+
@cpython_only
920+
@requires_debug_ranges()
921+
class CPythonTracebackErrorCaretTests(
922+
CAPIExceptionFormattingLegacyMixin,
923+
TracebackErrorLocationCaretTestBase,
924+
unittest.TestCase,
925+
):
926+
"""
927+
Same set of tests as above but with Python's legacy internal traceback printing.
928+
"""
915929

916930
class TracebackFormatTests(unittest.TestCase):
917931

Modules/_testcapi/exceptions.c

+13-3
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,22 @@ static PyObject *
4040
exception_print(PyObject *self, PyObject *args)
4141
{
4242
PyObject *exc;
43+
int legacy = 0;
4344

44-
if (!PyArg_ParseTuple(args, "O:exception_print", &exc)) {
45+
if (!PyArg_ParseTuple(args, "O|i:exception_print", &exc, &legacy)) {
4546
return NULL;
4647
}
47-
48-
PyErr_DisplayException(exc);
48+
if (legacy) {
49+
PyObject *tb = NULL;
50+
if (PyExceptionInstance_Check(exc)) {
51+
tb = PyException_GetTraceback(exc);
52+
}
53+
PyErr_Display((PyObject *) Py_TYPE(exc), exc, tb);
54+
Py_XDECREF(tb);
55+
}
56+
else {
57+
PyErr_DisplayException(exc);
58+
}
4959
Py_RETURN_NONE;
5060
}
5161

0 commit comments

Comments
 (0)