@@ -634,30 +634,18 @@ int
634
634
_PyGen_SetStopIterationValue (PyObject * value )
635
635
{
636
636
assert (!PyErr_Occurred ());
637
- PyObject * e ;
638
-
639
- if (value == NULL ||
640
- (!PyTuple_Check (value ) && !PyExceptionInstance_Check (value )))
641
- {
642
- /* Delay exception instantiation if we can */
643
- PyErr_SetObject (PyExc_StopIteration , value );
644
- return 0 ;
645
- }
646
- /* Construct an exception instance manually with
647
- * PyObject_CallOneArg and pass it to PyErr_SetObject.
648
- *
649
- * We do this to handle a situation when "value" is a tuple, in which
650
- * case PyErr_SetObject would set the value of StopIteration to
651
- * the first element of the tuple.
652
- *
653
- * (See PyErr_SetObject/_PyErr_CreateException code for details.)
654
- */
655
- e = PyObject_CallOneArg (PyExc_StopIteration , value );
656
- if (e == NULL ) {
637
+ // Construct an exception instance manually with PyObject_CallOneArg()
638
+ // but use PyErr_SetRaisedException() instead of PyErr_SetObject() as
639
+ // PyErr_SetObject(exc_type, value) has a fast path when 'value'
640
+ // is a tuple, where the value of the StopIteration exception would be
641
+ // set to 'value[0]' instead of 'value'.
642
+ PyObject * exc = value == NULL
643
+ ? PyObject_CallNoArgs (PyExc_StopIteration )
644
+ : PyObject_CallOneArg (PyExc_StopIteration , value );
645
+ if (exc == NULL ) {
657
646
return -1 ;
658
647
}
659
- PyErr_SetObject (PyExc_StopIteration , e );
660
- Py_DECREF (e );
648
+ PyErr_SetRaisedException (exc /* stolen */ );
661
649
return 0 ;
662
650
}
663
651
0 commit comments