Skip to content

Commit 9120330

Browse files
miss-islingtonpicnixzkumaraditya303
authored
[3.13] gh-128078: Use PyErr_SetRaisedException in _PyGen_SetStopIterationValue (GH-128287) (#128789)
gh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopIterationValue` (GH-128287) (cherry picked from commit 402b91d) Co-authored-by: Bénédikt Tran <[email protected]> Co-authored-by: Kumar Aditya <[email protected]>
1 parent 186165e commit 9120330

File tree

2 files changed

+11
-23
lines changed

2 files changed

+11
-23
lines changed

Lib/test/test_asyncgen.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,7 @@ async def run():
11651165
with self.assertRaises(StopAsyncIteration):
11661166
await it.__anext__()
11671167
res = await anext(it, ('a', 'b'))
1168-
self.assertEqual(res, ('a', 'b'))
1168+
self.assertTupleEqual(res, ('a', 'b'))
11691169

11701170
self.loop.run_until_complete(run())
11711171

Objects/genobject.c

+10-22
Original file line numberDiff line numberDiff line change
@@ -605,30 +605,18 @@ int
605605
_PyGen_SetStopIterationValue(PyObject *value)
606606
{
607607
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) {
628617
return -1;
629618
}
630-
PyErr_SetObject(PyExc_StopIteration, e);
631-
Py_DECREF(e);
619+
PyErr_SetRaisedException(exc /* stolen */);
632620
return 0;
633621
}
634622

0 commit comments

Comments
 (0)