commit f6c54042c50c48e939a698ef2146f11d29c2179a
parent f7a76f7e9618516fc054f18e3e8011fa06356ae9
Author: Joris Vink <joris@coders.se>
Date: Thu, 14 Jul 2022 10:56:27 +0200
Improve Python 3.10.x support.
Python 3.10.x its PyIter_Send() will return PYGEN_ERROR if the
generator returned (as opposed to yielding) if the result returned
is Py_None and no argument was given to PyIter_Send(). Which is counter
intuitive since it seems it should give us a PYGEN_RETURN as per its
documentation.
It also no longer sets PyExc_StopIteration in this case so we cannot depend
on that anymore to figure out if a coroutine has finished.
This caused Kore to respond with a 500 immediately after coroutines
ran to completion as it was looking for the PyExc_StopIteration exception.
Fix this by simply doing another check if an exception happened before
we enter the code path where Kore would spew the 500.
Diffstat:
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/python.c b/src/python.c
@@ -1090,7 +1090,12 @@ python_coro_run(struct python_coro *coro)
#if PY_VERSION_HEX < 0x030a00a1
item = _PyGen_Send((PyGenObject *)coro->obj, NULL);
#else
- /* Depend on the result in item only. */
+ /*
+ * Python 3.10.x its PyIter_Send() will return a PYGEN_ERROR
+ * if the coro returned (instead of yielding) and the result
+ * ends up being Py_None. This means the returned item is
+ * NULL but no StopIteration exception has occurred.
+ */
(void)PyIter_Send(coro->obj, NULL, &item);
#endif
@@ -1100,9 +1105,8 @@ python_coro_run(struct python_coro *coro)
PyErr_Fetch(&type, &coro->result, &traceback);
Py_DECREF(type);
Py_XDECREF(traceback);
- } else {
+ } else if (PyErr_Occurred()) {
kore_python_log_error("coroutine");
-
if (coro->request != NULL) {
http_response(coro->request,
HTTP_STATUS_INTERNAL_ERROR,