Skip to content

Commit

Permalink
gh-102755: PyErr_DisplayException only in ABI >= 3.12. Tests cover Py…
Browse files Browse the repository at this point in the history
…Err_Display as well (GH-102849)
  • Loading branch information
iritkatriel committed Mar 21, 2023
1 parent 82eb946 commit 5c471f3
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
3 changes: 3 additions & 0 deletions Include/pythonrun.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ PyAPI_FUNC(PyObject *) Py_CompileString(const char *, const char *, int);
PyAPI_FUNC(void) PyErr_Print(void);
PyAPI_FUNC(void) PyErr_PrintEx(int);
PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *);

#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000
PyAPI_FUNC(void) PyErr_DisplayException(PyObject *);
#endif


/* Stuff with no proper home (yet) */
Expand Down
16 changes: 15 additions & 1 deletion Lib/test/test_traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,18 +394,22 @@ def get_exception(self, callable, slice_start=0, slice_end=-1):


class CAPIExceptionFormattingMixin:
LEGACY = 0

def get_exception(self, callable, slice_start=0, slice_end=-1):
from _testcapi import exception_print
try:
callable()
self.fail("No exception thrown.")
except Exception as e:
with captured_output("stderr") as tbstderr:
exception_print(e)
exception_print(e, self.LEGACY)
return tbstderr.getvalue().splitlines()[slice_start:slice_end]

callable_line = get_exception.__code__.co_firstlineno + 3

class CAPIExceptionFormattingLegacyMixin(CAPIExceptionFormattingMixin):
LEGACY = 1

@requires_debug_ranges()
class TracebackErrorLocationCaretTestBase:
Expand Down Expand Up @@ -912,6 +916,16 @@ class CPythonTracebackErrorCaretTests(
Same set of tests as above but with Python's internal traceback printing.
"""

@cpython_only
@requires_debug_ranges()
class CPythonTracebackErrorCaretTests(
CAPIExceptionFormattingLegacyMixin,
TracebackErrorLocationCaretTestBase,
unittest.TestCase,
):
"""
Same set of tests as above but with Python's legacy internal traceback printing.
"""

class TracebackFormatTests(unittest.TestCase):

Expand Down
16 changes: 13 additions & 3 deletions Modules/_testcapi/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,22 @@ static PyObject *
exception_print(PyObject *self, PyObject *args)
{
PyObject *exc;
int legacy = 0;

if (!PyArg_ParseTuple(args, "O:exception_print", &exc)) {
if (!PyArg_ParseTuple(args, "O|i:exception_print", &exc, &legacy)) {
return NULL;
}

PyErr_DisplayException(exc);
if (legacy) {
PyObject *tb = NULL;
if (PyExceptionInstance_Check(exc)) {
tb = PyException_GetTraceback(exc);
}
PyErr_Display((PyObject *) Py_TYPE(exc), exc, tb);
Py_XDECREF(tb);
}
else {
PyErr_DisplayException(exc);
}
Py_RETURN_NONE;
}

Expand Down

0 comments on commit 5c471f3

Please sign in to comment.