From 703b4ef92df1f0058bc07543fde9754de2fecc95 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Jun 30 2022 16:02:15 +0000 Subject: Add Python 3.11 support Resolves: rhbz#2099185 --- diff --git a/uwsgi.spec b/uwsgi.spec index e4063f8..016d6a8 100644 --- a/uwsgi.spec +++ b/uwsgi.spec @@ -187,7 +187,7 @@ Name: uwsgi Version: 2.0.20 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Fast, self-healing, application container server # uwsgi is licensed under GPLv2 with a linking exception # docs are licensed under MIT @@ -216,6 +216,7 @@ Patch13: uwsgi_fix_chroot_chdir.patch # https://github.com/unbit/uwsgi/issues/2356 Patch14: uwsgi_fix_php_arginfo.patch Patch15: uwsgi_fix_python_py_ssize_t.patch +Patch16: uwsgi_python311.patch BuildRequires: curl, libxml2-devel, libuuid-devel, jansson-devel BuildRequires: libyaml-devel, ruby-devel @@ -1239,6 +1240,7 @@ cp -p %{SOURCE5} README.Fedora %patch13 -p1 %patch14 -p1 %patch15 -p1 +%patch16 -p1 %if %{with perl} && (%{with python3} || %{with python3_other}) && %{with perlcoro} %{__python} -m lib2to3 --write --nobackups plugins/coroae/uwsgiplugin.py @@ -1833,6 +1835,9 @@ exit 0 %changelog +* Thu Jun 30 2022 Victor Stinner - 2.0.20-7 +- Add Python 3.11 support (rhbz#2099185) + * Mon Jun 13 2022 Python Maint - 2.0.20-6 - Rebuilt for Python 3.11 diff --git a/uwsgi_python311.patch b/uwsgi_python311.patch new file mode 100644 index 0000000..ddf0a3d --- /dev/null +++ b/uwsgi_python311.patch @@ -0,0 +1,174 @@ +Add Python 3.11 support + +Backport of https://github.com/unbit/uwsgi/pull/2453 + +Resolves: rhbz#2099185 + +diff --git a/plugins/python/profiler.c b/plugins/python/profiler.c +index 92bc3da..2a7e1cc 100644 +--- a/plugins/python/profiler.c ++++ b/plugins/python/profiler.c +@@ -13,6 +13,14 @@ int PyFrame_GetLineNumber(PyFrameObject *frame) { + } + #endif + ++#if PY_VERSION_HEX < 0x030900B1 ++PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) ++{ ++ Py_INCREF(frame->f_code); ++ return frame->f_code; ++} ++#endif ++ + #ifdef PYTHREE + #undef PyString_AsString + static char *PyString_AsString(PyObject *o) { +@@ -27,27 +35,32 @@ int uwsgi_python_profiler_call(PyObject *obj, PyFrameObject *frame, int what, Py + static uint64_t last_ts = 0; + uint64_t now = uwsgi_micros(); + uint64_t delta = 0; ++ PyCodeObject *code; + + switch(what) { + case PyTrace_CALL: + if (last_ts == 0) delta = 0; + else delta = now - last_ts; + last_ts = now; ++ code = PyFrame_GetCode(frame); + uwsgi_log("[uWSGI Python profiler %llu] CALL: %s (line %d) -> %s %d args, stacksize %d\n", + (unsigned long long) delta, +- PyString_AsString(frame->f_code->co_filename), ++ PyString_AsString(code->co_filename), + PyFrame_GetLineNumber(frame), +- PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount, frame->f_code->co_stacksize); ++ PyString_AsString(code->co_name), code->co_argcount, code->co_stacksize); ++ Py_DECREF(code); + break; + case PyTrace_C_CALL: + if (last_ts == 0) delta = 0; + else delta = now - last_ts; + last_ts = now; ++ code = PyFrame_GetCode(frame); + uwsgi_log("[uWSGI Python profiler %llu] C CALL: %s (line %d) -> %s %d args, stacksize %d\n", + (unsigned long long) delta, +- PyString_AsString(frame->f_code->co_filename), ++ PyString_AsString(code->co_filename), + PyFrame_GetLineNumber(frame), +- PyEval_GetFuncName(arg), frame->f_code->co_argcount, frame->f_code->co_stacksize); ++ PyEval_GetFuncName(arg), code->co_argcount, code->co_stacksize); ++ Py_DECREF(code); + break; + } + +@@ -68,7 +81,9 @@ int uwsgi_python_tracer(PyObject *obj, PyFrameObject *frame, int what, PyObject + delta = now - last_ts; + } + last_ts = now; +- uwsgi_log("[uWSGI Python profiler %llu] file %s line %d: %s argc:%d\n", (unsigned long long)delta, PyString_AsString(frame->f_code->co_filename), PyFrame_GetLineNumber(frame), PyString_AsString(frame->f_code->co_name), frame->f_code->co_argcount); ++ PyCodeObject *code = PyFrame_GetCode(frame); ++ uwsgi_log("[uWSGI Python profiler %llu] file %s line %d: %s argc:%d\n", (unsigned long long)delta, PyString_AsString(code->co_filename), PyFrame_GetLineNumber(frame), PyString_AsString(code->co_name), code->co_argcount); ++ Py_DECREF(code); + } + + return 0; +diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c +index 6834f84..1d21c0d 100644 +--- a/plugins/python/python_plugin.c ++++ b/plugins/python/python_plugin.c +@@ -1137,9 +1137,13 @@ void uwsgi_python_init_apps() { + } + + // prepare for stack suspend/resume +- if (uwsgi.async > 1) { ++ if (uwsgi.async > 0) { ++#ifdef UWSGI_PY311 ++ up.current_recursion_remaining = uwsgi_malloc(sizeof(int)*uwsgi.async); ++#else + up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async); +- up.current_frame = uwsgi_malloc(sizeof(struct _frame)*uwsgi.async); ++#endif ++ up.current_frame = uwsgi_malloc(sizeof(up.current_frame[0])*uwsgi.async); + } + + // setup app loaders +@@ -1530,12 +1534,22 @@ void uwsgi_python_suspend(struct wsgi_request *wsgi_req) { + PyGILState_Release(pgst); + + if (wsgi_req) { ++#ifdef UWSGI_PY311 ++ up.current_recursion_remaining[wsgi_req->async_id] = tstate->recursion_remaining; ++ up.current_frame[wsgi_req->async_id] = tstate->cframe; ++#else + up.current_recursion_depth[wsgi_req->async_id] = tstate->recursion_depth; + up.current_frame[wsgi_req->async_id] = tstate->frame; ++#endif + } + else { ++#ifdef UWSGI_PY311 ++ up.current_main_recursion_remaining = tstate->recursion_remaining; ++ up.current_main_frame = tstate->cframe; ++#else + up.current_main_recursion_depth = tstate->recursion_depth; + up.current_main_frame = tstate->frame; ++#endif + } + + } +@@ -1763,12 +1777,22 @@ void uwsgi_python_resume(struct wsgi_request *wsgi_req) { + PyGILState_Release(pgst); + + if (wsgi_req) { ++#ifdef UWSGI_PY311 ++ tstate->recursion_remaining = up.current_recursion_remaining[wsgi_req->async_id]; ++ tstate->cframe = up.current_frame[wsgi_req->async_id]; ++#else + tstate->recursion_depth = up.current_recursion_depth[wsgi_req->async_id]; + tstate->frame = up.current_frame[wsgi_req->async_id]; ++#endif + } + else { ++#ifdef UWSGI_PY311 ++ tstate->recursion_remaining = up.current_main_recursion_remaining; ++ tstate->cframe = up.current_main_frame; ++#else + tstate->recursion_depth = up.current_main_recursion_depth; + tstate->frame = up.current_main_frame; ++#endif + } + + } +diff --git a/plugins/python/uwsgi_python.h b/plugins/python/uwsgi_python.h +index 357d731..6c6f7a4 100644 +--- a/plugins/python/uwsgi_python.h ++++ b/plugins/python/uwsgi_python.h +@@ -18,6 +18,10 @@ + #define UWSGI_PYTHON_OLD + #endif + ++#if (PY_VERSION_HEX >= 0x030b0000) ++# define UWSGI_PY311 ++#endif ++ + #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7 + #define HAS_NOT_PyMemoryView_FromBuffer + #endif +@@ -165,11 +169,19 @@ struct uwsgi_python { + + char *callable; + ++#ifdef UWSGI_PY311 ++ int *current_recursion_remaining; ++ _PyCFrame **current_frame; ++ ++ int current_main_recursion_remaining; ++ _PyCFrame *current_main_frame; ++#else + int *current_recursion_depth; + struct _frame **current_frame; + + int current_main_recursion_depth; + struct _frame *current_main_frame; ++#endif + + void (*swap_ts)(struct wsgi_request *, struct uwsgi_app *); + void (*reset_ts)(struct wsgi_request *, struct uwsgi_app *);