Skip to content

Commit 64396fb

Browse files
miss-islingtonpicnixzkumaraditya303
authored
[3.12] gh-128078: Use PyErr_SetRaisedException in _PyGen_SetStopIterationValue (GH-128287) (#128790)
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 6985b4b commit 64396fb

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
@@ -1113,7 +1113,7 @@ async def run():
11131113
with self.assertRaises(StopAsyncIteration):
11141114
await it.__anext__()
11151115
res = await anext(it, ('a', 'b'))
1116-
self.assertEqual(res, ('a', 'b'))
1116+
self.assertTupleEqual(res, ('a', 'b'))
11171117

11181118
self.loop.run_until_complete(run())
11191119

Objects/genobject.c

+10-22
Original file line numberDiff line numberDiff line change
@@ -619,30 +619,18 @@ int
619619
_PyGen_SetStopIterationValue(PyObject *value)
620620
{
621621
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) {
642631
return -1;
643632
}
644-
PyErr_SetObject(PyExc_StopIteration, e);
645-
Py_DECREF(e);
633+
PyErr_SetRaisedException(exc /* stolen */);
646634
return 0;
647635
}
648636

0 commit comments

Comments
 (0)