@@ -1058,6 +1058,23 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type,
1058
1058
static int do_raise (PyThreadState * tstate , PyObject * exc , PyObject * cause );
1059
1059
static int unpack_iterable (PyThreadState * , PyObject * , int , int , PyObject * * );
1060
1060
1061
+ #ifdef Py_DEBUG
1062
+ static void
1063
+ _assert_exception_type_is_redundant (PyObject * type , PyObject * val )
1064
+ {
1065
+ if (type == NULL || type == Py_None ) {
1066
+ assert (val == NULL || val == Py_None );
1067
+ }
1068
+ else {
1069
+ assert (PyExceptionInstance_Check (val ));
1070
+ assert (PyExceptionInstance_Class (val ) == type );
1071
+ }
1072
+ }
1073
+
1074
+ #define ASSERT_EXC_TYPE_IS_REDUNDANT (t , v ) _assert_exception_type_is_redundant(t, v)
1075
+ #else
1076
+ #define ASSERT_EXC_TYPE_IS_REDUNDANT (t , v )
1077
+ #endif
1061
1078
1062
1079
PyObject *
1063
1080
PyEval_EvalCode (PyObject * co , PyObject * globals , PyObject * locals )
@@ -2476,6 +2493,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
2476
2493
exc_info -> exc_type = POP ();
2477
2494
exc_info -> exc_value = POP ();
2478
2495
exc_info -> exc_traceback = POP ();
2496
+ ASSERT_EXC_TYPE_IS_REDUNDANT (exc_info -> exc_type , exc_info -> exc_value );
2479
2497
Py_XDECREF (type );
2480
2498
Py_XDECREF (value );
2481
2499
Py_XDECREF (traceback );
@@ -2497,6 +2515,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
2497
2515
type = POP ();
2498
2516
value = POP ();
2499
2517
traceback = POP ();
2518
+ ASSERT_EXC_TYPE_IS_REDUNDANT (type , value );
2500
2519
Py_DECREF (POP ()); /* lasti */
2501
2520
_PyErr_Restore (tstate , type , value , traceback );
2502
2521
exc_info = tstate -> exc_info ;
@@ -2506,6 +2525,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
2506
2525
exc_info -> exc_type = POP ();
2507
2526
exc_info -> exc_value = POP ();
2508
2527
exc_info -> exc_traceback = POP ();
2528
+ ASSERT_EXC_TYPE_IS_REDUNDANT (exc_info -> exc_type , exc_info -> exc_value );
2509
2529
Py_XDECREF (type );
2510
2530
Py_XDECREF (value );
2511
2531
Py_XDECREF (traceback );
@@ -2528,6 +2548,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
2528
2548
PyObject * exc = POP ();
2529
2549
PyObject * val = POP ();
2530
2550
PyObject * tb = POP ();
2551
+ ASSERT_EXC_TYPE_IS_REDUNDANT (exc , val );
2531
2552
assert (PyExceptionClass_Check (exc ));
2532
2553
_PyErr_Restore (tstate , exc , val , tb );
2533
2554
goto exception_unwind ;
@@ -2537,6 +2558,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
2537
2558
PyObject * exc = POP ();
2538
2559
PyObject * val = POP ();
2539
2560
PyObject * tb = POP ();
2561
+ ASSERT_EXC_TYPE_IS_REDUNDANT (exc , val );
2540
2562
assert (PyExceptionClass_Check (exc ));
2541
2563
if (PyErr_GivenExceptionMatches (exc , PyExc_StopAsyncIteration )) {
2542
2564
Py_DECREF (exc );
@@ -3991,6 +4013,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
3991
4013
exc = TOP ();
3992
4014
val = SECOND ();
3993
4015
tb = THIRD ();
4016
+ ASSERT_EXC_TYPE_IS_REDUNDANT (exc , val );
3994
4017
assert (!Py_IsNone (exc ));
3995
4018
assert (!PyLong_Check (exc ));
3996
4019
assert (PyLong_Check (PEEK (7 )));
@@ -4009,6 +4032,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
4009
4032
PyObject * type = TOP ();
4010
4033
PyObject * value = SECOND ();
4011
4034
PyObject * tb = THIRD ();
4035
+ ASSERT_EXC_TYPE_IS_REDUNDANT (type , value );
4012
4036
_PyErr_StackItem * exc_info = tstate -> exc_info ;
4013
4037
SET_THIRD (exc_info -> exc_traceback );
4014
4038
SET_SECOND (exc_info -> exc_value );
@@ -4990,6 +5014,7 @@ MISS_WITH_OPARG_COUNTER(BINARY_SUBSCR)
4990
5014
PUSH (tb );
4991
5015
PUSH (val );
4992
5016
PUSH (exc );
5017
+ ASSERT_EXC_TYPE_IS_REDUNDANT (exc , val );
4993
5018
JUMPTO (handler );
4994
5019
/* Resume normal execution */
4995
5020
frame -> f_state = FRAME_EXECUTING ;
0 commit comments