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():
--- /dev/null
+Add frame of ``except*`` to traceback when it wraps a naked exception.
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);
#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
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);
*/
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)) {
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);
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);