diff options
author | Victor Stinner <vstinner@python.org> | 2022-06-30 11:59:54 +0200 |
---|---|---|
committer | Victor Stinner <vstinner@python.org> | 2022-06-30 12:28:05 +0200 |
commit | 2768aea6cb20d6e8d171618f2217e29f5ded4ab5 (patch) | |
tree | 40d9e2e75b0c71a19ee1973c86526ab1f8fac7e3 | |
parent | ffced3256e6de7e841e4ca038620437f3c8042c0 (diff) | |
download | uwsgi-2768aea6cb20d6e8d171618f2217e29f5ded4ab5.tar.gz |
Add Python 3.11 support
* Use PyFrame_GetCode().
* Add PyFrame_GetCode() for Python 3.8 and older.
* Add UWSGI_PY311 macro: defined on Python 3.11 and newer.
* struct uwsgi_python: "current_recursion_depth" becomes
"current_recursion_remaining" and current_frame type becomes
_PyCFrame** on Python 3.11.
Related Python 3.11 changes:
* https://docs.python.org/dev/whatsnew/3.11.html#id6
* The PyFrameObject structure became opaque.
* PyThreadState.frame (PyFrameObject) became PyThreadState.cframe
(_PyCFrame) in Python 3.11.
* PyThreadState: recursion_depth was replaced with
recursion_remaining + recursion_limit.
-rw-r--r-- | plugins/python/profiler.c | 25 | ||||
-rw-r--r-- | plugins/python/python_plugin.c | 26 | ||||
-rw-r--r-- | plugins/python/uwsgi_python.h | 12 |
3 files changed, 57 insertions, 6 deletions
diff --git a/plugins/python/profiler.c b/plugins/python/profiler.c index 92bc3da7..2a7e1cc2 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 79f29d43..6c917c66 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -1185,8 +1185,12 @@ void uwsgi_python_init_apps() { // prepare for stack suspend/resume 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); } struct uwsgi_string_list *upli = up.import_list; @@ -1581,12 +1585,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 } } @@ -1814,12 +1828,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 ec64ad80..f91f7b43 100644 --- a/plugins/python/uwsgi_python.h +++ b/plugins/python/uwsgi_python.h @@ -16,6 +16,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 @@ -177,11 +181,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 *); |