gh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopIterationValue` (#128287)
https://github.com/python/cpython/commit/402b91da87052878b4e7e8946ba91bdf4ee... commit: 402b91da87052878b4e7e8946ba91bdf4ee4bebe branch: main author: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> committer: kumaraditya303 <kumaraditya@python.org> date: 2025-01-13T21:24:13+05:30 summary: gh-128078: Use `PyErr_SetRaisedException` in `_PyGen_SetStopIterationValue` (#128287) Co-authored-by: Kumar Aditya <kumaraditya@python.org> files: M Lib/test/test_asyncgen.py M Objects/genobject.c diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 3f631a03c9bf72..b81187871753b9 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -1165,7 +1165,7 @@ async def run(): with self.assertRaises(StopAsyncIteration): await it.__anext__() res = await anext(it, ('a', 'b')) - self.assertEqual(res, ('a', 'b')) + self.assertTupleEqual(res, ('a', 'b')) self.loop.run_until_complete(run()) diff --git a/Objects/genobject.c b/Objects/genobject.c index a4872de296e2cf..b32140766c4a38 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -634,30 +634,18 @@ int _PyGen_SetStopIterationValue(PyObject *value) { assert(!PyErr_Occurred()); - PyObject *e; - - if (value == NULL || - (!PyTuple_Check(value) && !PyExceptionInstance_Check(value))) - { - /* Delay exception instantiation if we can */ - PyErr_SetObject(PyExc_StopIteration, value); - return 0; - } - /* 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) { + // Construct an exception instance manually with PyObject_CallOneArg() + // but use PyErr_SetRaisedException() instead of PyErr_SetObject() as + // PyErr_SetObject(exc_type, value) has a fast path when 'value' + // is a tuple, where the value of the StopIteration exception would be + // set to 'value[0]' instead of 'value'. + PyObject *exc = value == NULL + ? PyObject_CallNoArgs(PyExc_StopIteration) + : PyObject_CallOneArg(PyExc_StopIteration, value); + if (exc == NULL) { return -1; } - PyErr_SetObject(PyExc_StopIteration, e); - Py_DECREF(e); + PyErr_SetRaisedException(exc /* stolen */); return 0; }
participants (1)
-
kumaraditya303