mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
[3.12] gh-128799: Add frame of except* to traceback when wrapping a naked exception (GH-128971) (#129328)
This commit is contained in:
parent
ddb314f598
commit
d2f551db12
5 changed files with 40 additions and 3 deletions
|
@ -2157,6 +2157,31 @@ class BaseExceptionReportingTests:
|
|||
report = self.get_report(exc)
|
||||
self.assertEqual(report, expected)
|
||||
|
||||
def test_exception_group_wrapped_naked(self):
|
||||
# See gh-128799
|
||||
|
||||
def exc():
|
||||
try:
|
||||
raise Exception(42)
|
||||
except* Exception as e:
|
||||
raise
|
||||
|
||||
expected = (f' + Exception Group Traceback (most recent call last):\n'
|
||||
f' | File "{__file__}", line {self.callable_line}, in get_exception\n'
|
||||
f' | exception_or_callable()\n'
|
||||
f' | File "{__file__}", line {exc.__code__.co_firstlineno + 3}, in exc\n'
|
||||
f' | except* Exception as e:\n'
|
||||
f' | ExceptionGroup: (1 sub-exception)\n'
|
||||
f' +-+---------------- 1 ----------------\n'
|
||||
f' | Traceback (most recent call last):\n'
|
||||
f' | File "{__file__}", line {exc.__code__.co_firstlineno + 2}, in exc\n'
|
||||
f' | raise Exception(42)\n'
|
||||
f' | Exception: 42\n'
|
||||
f' +------------------------------------\n')
|
||||
|
||||
report = self.get_report(exc)
|
||||
self.assertEqual(report, expected)
|
||||
|
||||
def test_KeyboardInterrupt_at_first_line_of_frame(self):
|
||||
# see GH-93249
|
||||
def f():
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Add frame of ``except*`` to traceback when it wraps a naked exception.
|
|
@ -2114,7 +2114,7 @@ dummy_func(
|
|||
|
||||
match = NULL;
|
||||
rest = NULL;
|
||||
int res = exception_group_match(exc_value, match_type,
|
||||
int res = exception_group_match(frame, exc_value, match_type,
|
||||
&match, &rest);
|
||||
DECREF_INPUTS();
|
||||
ERROR_IF(res < 0, error);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "pycore_range.h" // _PyRangeIterObject
|
||||
#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs
|
||||
#include "pycore_sysmodule.h" // _PySys_Audit()
|
||||
#include "pycore_traceback.h" // _PyTraceBack_FromFrame
|
||||
#include "pycore_tuple.h" // _PyTuple_ITEMS()
|
||||
#include "pycore_typeobject.h" // _PySuper_Lookup()
|
||||
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
|
||||
|
@ -544,6 +545,7 @@ fail:
|
|||
|
||||
static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause);
|
||||
static int exception_group_match(
|
||||
_PyInterpreterFrame *frame,
|
||||
PyObject* exc_value, PyObject *match_type,
|
||||
PyObject **match, PyObject **rest);
|
||||
|
||||
|
@ -1856,7 +1858,7 @@ raise_error:
|
|||
*/
|
||||
|
||||
static int
|
||||
exception_group_match(PyObject* exc_value, PyObject *match_type,
|
||||
exception_group_match(_PyInterpreterFrame *frame, PyObject* exc_value, PyObject *match_type,
|
||||
PyObject **match, PyObject **rest)
|
||||
{
|
||||
if (Py_IsNone(exc_value)) {
|
||||
|
@ -1883,6 +1885,15 @@ exception_group_match(PyObject* exc_value, PyObject *match_type,
|
|||
if (wrapped == NULL) {
|
||||
return -1;
|
||||
}
|
||||
PyFrameObject *f = _PyFrame_GetFrameObject(frame);
|
||||
if (f != NULL) {
|
||||
PyObject *tb = _PyTraceBack_FromFrame(NULL, f);
|
||||
if (tb == NULL) {
|
||||
return -1;
|
||||
}
|
||||
PyException_SetTraceback(wrapped, tb);
|
||||
Py_DECREF(tb);
|
||||
}
|
||||
*match = wrapped;
|
||||
}
|
||||
*rest = Py_NewRef(Py_None);
|
||||
|
|
2
Python/generated_cases.c.h
generated
2
Python/generated_cases.c.h
generated
|
@ -2952,7 +2952,7 @@
|
|||
|
||||
match = NULL;
|
||||
rest = NULL;
|
||||
int res = exception_group_match(exc_value, match_type,
|
||||
int res = exception_group_match(frame, exc_value, match_type,
|
||||
&match, &rest);
|
||||
#line 2958 "Python/generated_cases.c.h"
|
||||
Py_DECREF(exc_value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue