@@ -605,30 +605,18 @@ int
605
605
_PyGen_SetStopIterationValue (PyObject * value )
606
606
{
607
607
assert (!PyErr_Occurred ());
608
- PyObject * e ;
609
-
610
- if (value == NULL ||
611
- (!PyTuple_Check (value ) && !PyExceptionInstance_Check (value )))
612
- {
613
- /* Delay exception instantiation if we can */
614
- PyErr_SetObject (PyExc_StopIteration , value );
615
- return 0 ;
616
- }
617
- /* Construct an exception instance manually with
618
- * PyObject_CallOneArg and pass it to PyErr_SetObject.
619
- *
620
- * We do this to handle a situation when "value" is a tuple, in which
621
- * case PyErr_SetObject would set the value of StopIteration to
622
- * the first element of the tuple.
623
- *
624
- * (See PyErr_SetObject/_PyErr_CreateException code for details.)
625
- */
626
- e = PyObject_CallOneArg (PyExc_StopIteration , value );
627
- if (e == NULL ) {
608
+ // Construct an exception instance manually with PyObject_CallOneArg()
609
+ // but use PyErr_SetRaisedException() instead of PyErr_SetObject() as
610
+ // PyErr_SetObject(exc_type, value) has a fast path when 'value'
611
+ // is a tuple, where the value of the StopIteration exception would be
612
+ // set to 'value[0]' instead of 'value'.
613
+ PyObject * exc = value == NULL
614
+ ? PyObject_CallNoArgs (PyExc_StopIteration )
615
+ : PyObject_CallOneArg (PyExc_StopIteration , value );
616
+ if (exc == NULL ) {
628
617
return -1 ;
629
618
}
630
- PyErr_SetObject (PyExc_StopIteration , e );
631
- Py_DECREF (e );
619
+ PyErr_SetRaisedException (exc /* stolen */ );
632
620
return 0 ;
633
621
}
634
622
0 commit comments