mirror of https://github.com/python/cpython
gh-102755: PyErr_DisplayException only in ABI >= 3.12. Tests cover PyErr_Display as well (GH-102849)
This commit is contained in:
parent
82eb9469e7
commit
5c471f3f2a
|
@ -12,7 +12,10 @@ PyAPI_FUNC(PyObject *) Py_CompileString(const char *, const char *, int);
|
||||||
PyAPI_FUNC(void) PyErr_Print(void);
|
PyAPI_FUNC(void) PyErr_Print(void);
|
||||||
PyAPI_FUNC(void) PyErr_PrintEx(int);
|
PyAPI_FUNC(void) PyErr_PrintEx(int);
|
||||||
PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *);
|
PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *);
|
||||||
|
|
||||||
|
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000
|
||||||
PyAPI_FUNC(void) PyErr_DisplayException(PyObject *);
|
PyAPI_FUNC(void) PyErr_DisplayException(PyObject *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Stuff with no proper home (yet) */
|
/* Stuff with no proper home (yet) */
|
||||||
|
|
|
@ -394,6 +394,8 @@ class PurePythonExceptionFormattingMixin:
|
||||||
|
|
||||||
|
|
||||||
class CAPIExceptionFormattingMixin:
|
class CAPIExceptionFormattingMixin:
|
||||||
|
LEGACY = 0
|
||||||
|
|
||||||
def get_exception(self, callable, slice_start=0, slice_end=-1):
|
def get_exception(self, callable, slice_start=0, slice_end=-1):
|
||||||
from _testcapi import exception_print
|
from _testcapi import exception_print
|
||||||
try:
|
try:
|
||||||
|
@ -401,11 +403,13 @@ class CAPIExceptionFormattingMixin:
|
||||||
self.fail("No exception thrown.")
|
self.fail("No exception thrown.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
with captured_output("stderr") as tbstderr:
|
with captured_output("stderr") as tbstderr:
|
||||||
exception_print(e)
|
exception_print(e, self.LEGACY)
|
||||||
return tbstderr.getvalue().splitlines()[slice_start:slice_end]
|
return tbstderr.getvalue().splitlines()[slice_start:slice_end]
|
||||||
|
|
||||||
callable_line = get_exception.__code__.co_firstlineno + 3
|
callable_line = get_exception.__code__.co_firstlineno + 3
|
||||||
|
|
||||||
|
class CAPIExceptionFormattingLegacyMixin(CAPIExceptionFormattingMixin):
|
||||||
|
LEGACY = 1
|
||||||
|
|
||||||
@requires_debug_ranges()
|
@requires_debug_ranges()
|
||||||
class TracebackErrorLocationCaretTestBase:
|
class TracebackErrorLocationCaretTestBase:
|
||||||
|
@ -912,6 +916,16 @@ class CPythonTracebackErrorCaretTests(
|
||||||
Same set of tests as above but with Python's internal traceback printing.
|
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):
|
class TracebackFormatTests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,22 @@ static PyObject *
|
||||||
exception_print(PyObject *self, PyObject *args)
|
exception_print(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *exc;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (legacy) {
|
||||||
PyErr_DisplayException(exc);
|
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;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue