gh-128078: Use PyErr_SetRaisedException in _PyGen_SetStopIterationValue (#128287)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Bénédikt Tran 2025-01-13 16:54:13 +01:00 committed by GitHub
parent 3efe28a40b
commit 402b91da87
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 11 additions and 23 deletions

View file

@ -1165,7 +1165,7 @@ class AsyncGenAsyncioTest(unittest.TestCase):
with self.assertRaises(StopAsyncIteration): with self.assertRaises(StopAsyncIteration):
await it.__anext__() await it.__anext__()
res = await anext(it, ('a', 'b')) res = await anext(it, ('a', 'b'))
self.assertEqual(res, ('a', 'b')) self.assertTupleEqual(res, ('a', 'b'))
self.loop.run_until_complete(run()) self.loop.run_until_complete(run())

View file

@ -634,30 +634,18 @@ int
_PyGen_SetStopIterationValue(PyObject *value) _PyGen_SetStopIterationValue(PyObject *value)
{ {
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
PyObject *e; // Construct an exception instance manually with PyObject_CallOneArg()
// but use PyErr_SetRaisedException() instead of PyErr_SetObject() as
if (value == NULL || // PyErr_SetObject(exc_type, value) has a fast path when 'value'
(!PyTuple_Check(value) && !PyExceptionInstance_Check(value))) // is a tuple, where the value of the StopIteration exception would be
{ // set to 'value[0]' instead of 'value'.
/* Delay exception instantiation if we can */ PyObject *exc = value == NULL
PyErr_SetObject(PyExc_StopIteration, value); ? PyObject_CallNoArgs(PyExc_StopIteration)
return 0; : PyObject_CallOneArg(PyExc_StopIteration, value);
} if (exc == NULL) {
/* Construct an exception instance manually with
* PyObject_CallOneArg and pass it to PyErr_SetObject.
*
* We do this to handle a situation when "value" is a tuple, in which
* case PyErr_SetObject would set the value of StopIteration to
* the first element of the tuple.
*
* (See PyErr_SetObject/_PyErr_CreateException code for details.)
*/
e = PyObject_CallOneArg(PyExc_StopIteration, value);
if (e == NULL) {
return -1; return -1;
} }
PyErr_SetObject(PyExc_StopIteration, e); PyErr_SetRaisedException(exc /* stolen */);
Py_DECREF(e);
return 0; return 0;
} }