Skip to content

Commit

Permalink
This adds support for Python 3.12
Browse files Browse the repository at this point in the history
The code compiles, and runs all my (admittedly pretty primitive) web
applications. There may still be hidden issues in more complicated
scenarios (like threading support).
  • Loading branch information
Lalufu committed Sep 30, 2023
1 parent b3e09ce commit 6c937ba
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 6 deletions.
47 changes: 42 additions & 5 deletions plugins/python/python_plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ void uwsgi_python_pthread_child(void) {
PyMethodDef uwsgi_spit_method[] = { {"uwsgi_spit", py_uwsgi_spit, METH_VARARGS, ""} };
PyMethodDef uwsgi_write_method[] = { {"uwsgi_write", py_uwsgi_write, METH_VARARGS, ""} };

#ifdef PYTHREE
PyObject *init_uwsgi3(void);
#endif
int uwsgi_python_init() {

char *pyversion = strchr(Py_GetVersion(), '\n');
Expand Down Expand Up @@ -298,6 +301,9 @@ int uwsgi_python_init() {
wchar_t *pname = uwsgi_calloc(sizeof(wchar_t) * (strlen(program_name)+1));
mbstowcs(pname, program_name, strlen(program_name)+1);
Py_SetProgramName(pname);
#ifdef UWSGI_PY312
PyImport_AppendInittab("uwsgi", init_uwsgi3);
#endif
#else
Py_SetProgramName(program_name);
#endif
Expand Down Expand Up @@ -695,7 +701,9 @@ void init_uwsgi_embedded_module() {


#ifdef PYTHREE
#ifndef UWSGI_PY312
PyImport_AppendInittab("uwsgi", init_uwsgi3);
#endif
new_uwsgi_module = PyImport_AddModule("uwsgi");
#else
new_uwsgi_module = Py_InitModule3("uwsgi", NULL, uwsgi_py_doc);
Expand Down Expand Up @@ -1208,7 +1216,10 @@ void uwsgi_python_init_apps() {

// prepare for stack suspend/resume
if (uwsgi.async > 0) {
#ifdef UWSGI_PY311
#ifdef UWSGI_PY312
up.current_c_recursion_remaining = uwsgi_malloc(sizeof(int)*uwsgi.async);
up.current_py_recursion_remaining = uwsgi_malloc(sizeof(int)*uwsgi.async);
#elif defined UWSGI_PY311
up.current_recursion_remaining = uwsgi_malloc(sizeof(int)*uwsgi.async);
#else
up.current_recursion_depth = uwsgi_malloc(sizeof(int)*uwsgi.async);
Expand Down Expand Up @@ -1360,7 +1371,12 @@ void uwsgi_python_pre_uwsgi_fork() {
// Acquire the gil and import lock before forking in order to avoid
// deadlocks in workers
UWSGI_GET_GIL
#if defined UWSGI_PY312
PyInterpreterState *interp = PyInterpreterState_Get();
_PyImport_AcquireLock(interp);
#else
_PyImport_AcquireLock();
#endif
}
}

Expand All @@ -1372,7 +1388,12 @@ void uwsgi_python_post_uwsgi_fork(int step) {
if (uwsgi.has_threads) {
if (step == 0) {
// Release locks within master process
#if defined UWSGI_PY312
PyInterpreterState *interp = PyInterpreterState_Get();
_PyImport_ReleaseLock(interp);
#else
_PyImport_ReleaseLock();
#endif
UWSGI_RELEASE_GIL
}
else {
Expand Down Expand Up @@ -1643,7 +1664,11 @@ void uwsgi_python_suspend(struct wsgi_request *wsgi_req) {
PyGILState_Release(pgst);

if (wsgi_req) {
#ifdef UWSGI_PY311
#ifdef UWSGI_PY312
up.current_c_recursion_remaining[wsgi_req->async_id] = tstate->c_recursion_remaining;
up.current_py_recursion_remaining[wsgi_req->async_id] = tstate->py_recursion_remaining;
up.current_frame[wsgi_req->async_id] = tstate->cframe;
#elif defined UWSGI_PY311
up.current_recursion_remaining[wsgi_req->async_id] = tstate->recursion_remaining;
up.current_frame[wsgi_req->async_id] = tstate->cframe;
#else
Expand All @@ -1652,7 +1677,11 @@ void uwsgi_python_suspend(struct wsgi_request *wsgi_req) {
#endif
}
else {
#ifdef UWSGI_PY311
#ifdef UWSGI_PY312
up.current_main_c_recursion_remaining = tstate->c_recursion_remaining;
up.current_main_py_recursion_remaining = tstate->py_recursion_remaining;
up.current_main_frame = tstate->cframe;
#elif defined UWSGI_PY311
up.current_main_recursion_remaining = tstate->recursion_remaining;
up.current_main_frame = tstate->cframe;
#else
Expand Down Expand Up @@ -1886,7 +1915,11 @@ void uwsgi_python_resume(struct wsgi_request *wsgi_req) {
PyGILState_Release(pgst);

if (wsgi_req) {
#ifdef UWSGI_PY311
#ifdef UWSGI_PY312
tstate->c_recursion_remaining = up.current_c_recursion_remaining[wsgi_req->async_id];
tstate->py_recursion_remaining = up.current_py_recursion_remaining[wsgi_req->async_id];
tstate->cframe = up.current_frame[wsgi_req->async_id];
#elif defined UWSGI_PY311
tstate->recursion_remaining = up.current_recursion_remaining[wsgi_req->async_id];
tstate->cframe = up.current_frame[wsgi_req->async_id];
#else
Expand All @@ -1895,7 +1928,11 @@ void uwsgi_python_resume(struct wsgi_request *wsgi_req) {
#endif
}
else {
#ifdef UWSGI_PY311
#ifdef UWSGI_PY312
tstate->c_recursion_remaining = up.current_main_c_recursion_remaining;
tstate->py_recursion_remaining = up.current_main_py_recursion_remaining;
tstate->cframe = up.current_main_frame;
#elif defined UWSGI_PY311
tstate->recursion_remaining = up.current_main_recursion_remaining;
tstate->cframe = up.current_main_frame;
#else
Expand Down
14 changes: 13 additions & 1 deletion plugins/python/uwsgi_python.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# define UWSGI_PY311
#endif

#if (PY_VERSION_HEX >= 0x030c0000)
# define UWSGI_PY312
#endif

#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 7
#define HAS_NOT_PyMemoryView_FromBuffer
#endif
Expand Down Expand Up @@ -182,7 +186,15 @@ struct uwsgi_python {

char *callable;

#ifdef UWSGI_PY311
#ifdef UWSGI_PY312
int *current_c_recursion_remaining;
int *current_py_recursion_remaining;
_PyCFrame **current_frame;

int current_main_c_recursion_remaining;
int current_main_py_recursion_remaining;
_PyCFrame *current_main_frame;
#elif defined UWSGI_PY311
int *current_recursion_remaining;
_PyCFrame **current_frame;

Expand Down

0 comments on commit 6c937ba

Please sign in to comment.