@@ -3786,16 +3786,13 @@ PyObject *
3786
3786
_PyErr_TrySetFromCause (const char * format , ...)
3787
3787
{
3788
3788
PyObject * msg_prefix ;
3789
- PyObject * exc , * val , * tb ;
3790
- PyTypeObject * caught_type ;
3791
3789
PyObject * instance_args ;
3792
3790
Py_ssize_t num_args , caught_type_size , base_exc_size ;
3793
- PyObject * new_exc , * new_val , * new_tb ;
3794
3791
va_list vargs ;
3795
3792
int same_basic_size ;
3796
3793
3797
- PyErr_Fetch ( & exc , & val , & tb );
3798
- caught_type = ( PyTypeObject * ) exc ;
3794
+ PyObject * exc = PyErr_GetRaisedException ( );
3795
+ PyTypeObject * caught_type = Py_TYPE ( exc ) ;
3799
3796
/* Ensure type info indicates no extra state is stored at the C level
3800
3797
* and that the type can be reinstantiated using PyErr_Format
3801
3798
*/
@@ -3815,31 +3812,30 @@ _PyErr_TrySetFromCause(const char *format, ...)
3815
3812
* more state than just the exception type. Accordingly, we just
3816
3813
* leave it alone.
3817
3814
*/
3818
- PyErr_Restore (exc , val , tb );
3815
+ PyErr_SetRaisedException (exc );
3819
3816
return NULL ;
3820
3817
}
3821
3818
3822
3819
/* Check the args are empty or contain a single string */
3823
- PyErr_NormalizeException (& exc , & val , & tb );
3824
- instance_args = ((PyBaseExceptionObject * )val )-> args ;
3820
+ instance_args = ((PyBaseExceptionObject * )exc )-> args ;
3825
3821
num_args = PyTuple_GET_SIZE (instance_args );
3826
3822
if (num_args > 1 ||
3827
3823
(num_args == 1 &&
3828
3824
!PyUnicode_CheckExact (PyTuple_GET_ITEM (instance_args , 0 )))) {
3829
3825
/* More than 1 arg, or the one arg we do have isn't a string
3830
3826
*/
3831
- PyErr_Restore (exc , val , tb );
3827
+ PyErr_SetRaisedException (exc );
3832
3828
return NULL ;
3833
3829
}
3834
3830
3835
3831
/* Ensure the instance dict is also empty */
3836
- if (!_PyObject_IsInstanceDictEmpty (val )) {
3832
+ if (!_PyObject_IsInstanceDictEmpty (exc )) {
3837
3833
/* While we could potentially copy a non-empty instance dictionary
3838
3834
* to the replacement exception, for now we take the more
3839
3835
* conservative path of leaving exceptions with attributes set
3840
3836
* alone.
3841
3837
*/
3842
- PyErr_Restore (exc , val , tb );
3838
+ PyErr_SetRaisedException (exc );
3843
3839
return NULL ;
3844
3840
}
3845
3841
@@ -3852,28 +3848,18 @@ _PyErr_TrySetFromCause(const char *format, ...)
3852
3848
* types as well, but that's quite a bit trickier due to the extra
3853
3849
* state potentially stored on OSError instances.
3854
3850
*/
3855
- /* Ensure the traceback is set correctly on the existing exception */
3856
- if (tb != NULL ) {
3857
- PyException_SetTraceback (val , tb );
3858
- Py_DECREF (tb );
3859
- }
3860
-
3861
3851
va_start (vargs , format );
3862
3852
msg_prefix = PyUnicode_FromFormatV (format , vargs );
3863
3853
va_end (vargs );
3864
3854
if (msg_prefix == NULL ) {
3865
- Py_DECREF (exc );
3866
- Py_DECREF (val );
3867
3855
return NULL ;
3868
3856
}
3869
3857
3870
- PyErr_Format (exc , "%U (%s: %S)" ,
3871
- msg_prefix , Py_TYPE (val )-> tp_name , val );
3872
- Py_DECREF (exc );
3858
+ PyErr_Format ((PyObject * )Py_TYPE (exc ), "%U (%s: %S)" ,
3859
+ msg_prefix , Py_TYPE (exc )-> tp_name , exc );
3873
3860
Py_DECREF (msg_prefix );
3874
- PyErr_Fetch (& new_exc , & new_val , & new_tb );
3875
- PyErr_NormalizeException (& new_exc , & new_val , & new_tb );
3876
- PyException_SetCause (new_val , val );
3877
- PyErr_Restore (new_exc , new_val , new_tb );
3878
- return new_val ;
3861
+ PyObject * new_exc = PyErr_GetRaisedException ();
3862
+ PyException_SetCause (new_exc , exc );
3863
+ PyErr_SetRaisedException (new_exc );
3864
+ return new_exc ;
3879
3865
}
0 commit comments