summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-06-30 11:59:54 +0200
committerVictor Stinner <vstinner@python.org>2022-06-30 12:28:05 +0200
commit2768aea6cb20d6e8d171618f2217e29f5ded4ab5 (patch)
tree40d9e2e75b0c71a19ee1973c86526ab1f8fac7e3
parentffced3256e6de7e841e4ca038620437f3c8042c0 (diff)
downloaduwsgi-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.c25
-rw-r--r--plugins/python/python_plugin.c26
-rw-r--r--plugins/python/uwsgi_python.h12
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 *);