| 1 | Patch-Source: https://github.com/FreeRADIUS/freeradius-server/pull/5208
|
| 2 | ---
|
| 3 | From d6dcbbf38045a851007606ebdf11fb5ae5ddd0ff Mon Sep 17 00:00:00 2001
|
| 4 | From: Antonio Torres <[email protected]>
|
| 5 | Date: Tue, 24 Oct 2023 13:31:33 +0200
|
| 6 | Subject: [PATCH] Fix build errors with Python 3.13
|
| 7 |
|
| 8 | According to [1], the `PyEval_InitThreads()` (deprecated 3.9), `PyEval_AcquireLock()` and
|
| 9 | `PyEval_ReleaseLock()` (deprecated 3.2). functions, are removed in Python 3.13. `Py_SetProgramName()`
|
| 10 | is deprecated since 3.11 as well.
|
| 11 |
|
| 12 | `PyEval_InitThreads` can be deleted if running Python >= 3.10 as it simply does
|
| 13 | nothing from Python 3.9 [2].
|
| 14 |
|
| 15 | Lock functions are replaced with `PyEval_RestoreThread` and
|
| 16 | `PyEval_SaveThread` as advised by Python docs [3], [4].
|
| 17 |
|
| 18 | As for `Py_SetProgramName`, it should be replaced with PyConfig. The
|
| 19 | config is isolated to replicate behavior of `InitializeEx` [5].
|
| 20 |
|
| 21 | [1]: https://docs.python.org/3.13/whatsnew/3.13.html
|
| 22 | [2]: https://docs.python.org/3/c-api/init.html#c.PyEval_InitThreads
|
| 23 | [3]: https://docs.python.org/3/c-api/init.html#c.PyEval_AcquireLock
|
| 24 | [4]: https://docs.python.org/3/c-api/init.html#c.PyEval_ReleaseLock
|
| 25 | [5]: https://docs.python.org/3/c-api/init_config.html#isolated-configuration
|
| 26 | ---
|
| 27 | src/modules/rlm_python3/rlm_python3.c | 31 ++++++++++++++++++++++-----
|
| 28 | 1 file changed, 26 insertions(+), 5 deletions(-)
|
| 29 |
|
| 30 | diff --git a/src/modules/rlm_python3/rlm_python3.c b/src/modules/rlm_python3/rlm_python3.c
|
| 31 | index a200a988aeea9..c548a1201bcd2 100644
|
| 32 | |
| 33 | |
| 34 | @@ -679,12 +679,10 @@ static rlm_rcode_t do_python_single(REQUEST *request, PyObject *pFunc, char cons
|
| 35 |
|
| 36 | static void python_interpreter_free(PyThreadState *interp)
|
| 37 | {
|
| 38 | -DIAG_OFF(deprecated-declarations)
|
| 39 | - PyEval_AcquireLock();
|
| 40 | + PyEval_RestoreThread(interp);
|
| 41 | PyThreadState_Swap(interp);
|
| 42 | Py_EndInterpreter(interp);
|
| 43 | - PyEval_ReleaseLock();
|
| 44 | -DIAG_ON(deprecated-declarations)
|
| 45 | + PyEval_SaveThread();
|
| 46 | }
|
| 47 |
|
| 48 | /** Destroy a thread state
|
| 49 | @@ -1117,7 +1115,21 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
|
| 50 | python_dlhandle = dlopen_libpython(RTLD_NOW | RTLD_GLOBAL);
|
| 51 | if (!python_dlhandle) WARN("Failed loading libpython symbols into global symbol table");
|
| 52 |
|
| 53 | -#if PY_VERSION_HEX >= 0x03050000
|
| 54 | +#if PY_VERSION_HEX > 0x030a0000
|
| 55 | + PyStatus status;
|
| 56 | +
|
| 57 | + PyConfig config;
|
| 58 | + PyConfig_InitIsolatedConfig(&config); /* Isolated config: Don't override signal handlers - noop on subs calls */
|
| 59 | +
|
| 60 | + wchar_t *name;
|
| 61 | + MEM(name = Py_DecodeLocale(main_config.name, NULL)); /* The value of argv[0] as a wide char string */
|
| 62 | + status = PyConfig_SetString(&config, &config.program_name, name);
|
| 63 | + if (PyStatus_Exception(status)) {
|
| 64 | + PyConfig_Clear(&config);
|
| 65 | + return -1;
|
| 66 | + }
|
| 67 | + PyMem_RawFree(name);
|
| 68 | +#elif PY_VERSION_HEX >= 0x03050000
|
| 69 | {
|
| 70 | wchar_t *name;
|
| 71 |
|
| 72 | @@ -1134,8 +1146,17 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
|
| 73 | }
|
| 74 | #endif
|
| 75 |
|
| 76 | +#if PY_VERSION_HEX > 0x030a0000
|
| 77 | + status = Py_InitializeFromConfig(&config);
|
| 78 | + if (PyStatus_Exception(status)) {
|
| 79 | + PyConfig_Clear(&config);
|
| 80 | + return -1;
|
| 81 | + }
|
| 82 | + PyConfig_Clear(&config);
|
| 83 | +#else
|
| 84 | Py_InitializeEx(0); /* Don't override signal handlers - noop on subs calls */
|
| 85 | PyEval_InitThreads(); /* This also grabs a lock (which we then need to release) */
|
| 86 | +#endif
|
| 87 | main_interpreter = PyThreadState_Get(); /* Store reference to the main interpreter */
|
| 88 | locked = true;
|
| 89 | }
|