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