@@ -470,25 +470,43 @@ PyErr_Clear(void)
470
470
_PyErr_Clear (tstate );
471
471
}
472
472
473
+ static PyObject *
474
+ get_exc_type (PyObject * exc_value ) /* returns a borrowed ref */
475
+ {
476
+ if (exc_value == NULL || exc_value == Py_None ) {
477
+ return Py_None ;
478
+ }
479
+ else {
480
+ assert (PyExceptionInstance_Check (exc_value ));
481
+ PyObject * type = PyExceptionInstance_Class (exc_value );
482
+ assert (type != NULL );
483
+ return type ;
484
+ }
485
+ }
486
+
487
+ static PyObject *
488
+ get_exc_traceback (PyObject * exc_value ) /* returns a borrowed ref */
489
+ {
490
+ if (exc_value == NULL || exc_value == Py_None ) {
491
+ return Py_None ;
492
+ }
493
+ else {
494
+ assert (PyExceptionInstance_Check (exc_value ));
495
+ PyObject * tb = PyException_GetTraceback (exc_value );
496
+ Py_XDECREF (tb );
497
+ return tb ? tb : Py_None ;
498
+ }
499
+ }
473
500
474
501
void
475
502
_PyErr_GetExcInfo (PyThreadState * tstate ,
476
503
PyObject * * p_type , PyObject * * p_value , PyObject * * p_traceback )
477
504
{
478
505
_PyErr_StackItem * exc_info = _PyErr_GetTopmostException (tstate );
479
506
507
+ * p_type = get_exc_type (exc_info -> exc_value );
480
508
* p_value = exc_info -> exc_value ;
481
- * p_traceback = exc_info -> exc_traceback ;
482
-
483
- if (* p_value == NULL || * p_value == Py_None ) {
484
- assert (exc_info -> exc_type == NULL || exc_info -> exc_type == Py_None );
485
- * p_type = Py_None ;
486
- }
487
- else {
488
- assert (PyExceptionInstance_Check (* p_value ));
489
- assert (exc_info -> exc_type == PyExceptionInstance_Class (* p_value ));
490
- * p_type = PyExceptionInstance_Class (* p_value );
491
- }
509
+ * p_traceback = get_exc_traceback (exc_info -> exc_value );
492
510
493
511
Py_XINCREF (* p_type );
494
512
Py_XINCREF (* p_value );
@@ -504,7 +522,7 @@ PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
504
522
}
505
523
506
524
void
507
- PyErr_SetExcInfo (PyObject * p_type , PyObject * p_value , PyObject * p_traceback )
525
+ PyErr_SetExcInfo (PyObject * type , PyObject * value , PyObject * traceback )
508
526
{
509
527
PyObject * oldtype , * oldvalue , * oldtraceback ;
510
528
PyThreadState * tstate = _PyThreadState_GET ();
@@ -513,9 +531,16 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
513
531
oldvalue = tstate -> exc_info -> exc_value ;
514
532
oldtraceback = tstate -> exc_info -> exc_traceback ;
515
533
516
- tstate -> exc_info -> exc_type = p_type ;
517
- tstate -> exc_info -> exc_value = p_value ;
518
- tstate -> exc_info -> exc_traceback = p_traceback ;
534
+
535
+ tstate -> exc_info -> exc_type = get_exc_type (value );
536
+ Py_XINCREF (tstate -> exc_info -> exc_type );
537
+ tstate -> exc_info -> exc_value = value ;
538
+ tstate -> exc_info -> exc_traceback = get_exc_traceback (value );
539
+ Py_XINCREF (tstate -> exc_info -> exc_traceback );
540
+
541
+ /* These args are no longer used, but we still need to steal a ref */
542
+ Py_XDECREF (type );
543
+ Py_XDECREF (traceback );
519
544
520
545
Py_XDECREF (oldtype );
521
546
Py_XDECREF (oldvalue );
@@ -527,22 +552,19 @@ PyObject*
527
552
_PyErr_StackItemToExcInfoTuple (_PyErr_StackItem * err_info )
528
553
{
529
554
PyObject * exc_value = err_info -> exc_value ;
530
- if (exc_value == NULL ) {
531
- exc_value = Py_None ;
532
- }
533
555
534
- assert (exc_value == Py_None || PyExceptionInstance_Check (exc_value ));
556
+ assert (exc_value == NULL ||
557
+ exc_value == Py_None ||
558
+ PyExceptionInstance_Check (exc_value ));
535
559
536
- PyObject * exc_type = PyExceptionInstance_Check (exc_value ) ?
537
- PyExceptionInstance_Class (exc_value ) :
538
- Py_None ;
560
+ PyObject * exc_type = get_exc_type (exc_value );
561
+ PyObject * exc_traceback = get_exc_traceback (exc_value );
539
562
540
563
return Py_BuildValue (
541
564
"(OOO)" ,
542
- exc_type ,
543
- exc_value ,
544
- err_info -> exc_traceback != NULL ?
545
- err_info -> exc_traceback : Py_None );
565
+ exc_type ? exc_type : Py_None ,
566
+ exc_value ? exc_value : Py_None ,
567
+ exc_traceback ? exc_traceback : Py_None );
546
568
}
547
569
548
570
0 commit comments