aports/main/freeradius/python-3.14.patch
mio 6c9b01e0bd main/freeradius: fix build with python 3.14
Fix build error from calls to functions removed in python >=3.13. Error
found on the edge builders.

```
src/modules/rlm_python3/rlm_python3.c: In function 'python_interpreter_free':
src/modules/rlm_python3/rlm_python3.c:692:9: error: implicit declaration of function 'PyEval_AcquireLock'; did you mean 'PyEval_AcquireThread'? [-Wimplicit-function-declaration]
  692 |         PyEval_AcquireLock();
      |         ^~~~~~~~~~~~~~~~~~
      |         PyEval_AcquireThread
src/modules/rlm_python3/rlm_python3.c:695:9: error: implicit declaration of function 'PyEval_ReleaseLock'; did you mean 'PyEval_ReleaseThread'? [-Wimplicit-function-declaration]
  695 |         PyEval_ReleaseLock();
      |         ^~~~~~~~~~~~~~~~~~
```
2026-03-28 00:34:39 +00:00

90 lines
3.4 KiB
Diff

Patch-Source: https://github.com/FreeRADIUS/freeradius-server/pull/5208
---
From d6dcbbf38045a851007606ebdf11fb5ae5ddd0ff Mon Sep 17 00:00:00 2001
From: Antonio Torres <antorres@redhat.com>
Date: Tue, 24 Oct 2023 13:31:33 +0200
Subject: [PATCH] Fix build errors with Python 3.13
According to [1], the `PyEval_InitThreads()` (deprecated 3.9), `PyEval_AcquireLock()` and
`PyEval_ReleaseLock()` (deprecated 3.2). functions, are removed in Python 3.13. `Py_SetProgramName()`
is deprecated since 3.11 as well.
`PyEval_InitThreads` can be deleted if running Python >= 3.10 as it simply does
nothing from Python 3.9 [2].
Lock functions are replaced with `PyEval_RestoreThread` and
`PyEval_SaveThread` as advised by Python docs [3], [4].
As for `Py_SetProgramName`, it should be replaced with PyConfig. The
config is isolated to replicate behavior of `InitializeEx` [5].
[1]: https://docs.python.org/3.13/whatsnew/3.13.html
[2]: https://docs.python.org/3/c-api/init.html#c.PyEval_InitThreads
[3]: https://docs.python.org/3/c-api/init.html#c.PyEval_AcquireLock
[4]: https://docs.python.org/3/c-api/init.html#c.PyEval_ReleaseLock
[5]: https://docs.python.org/3/c-api/init_config.html#isolated-configuration
---
src/modules/rlm_python3/rlm_python3.c | 31 ++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/src/modules/rlm_python3/rlm_python3.c b/src/modules/rlm_python3/rlm_python3.c
index a200a988aeea9..c548a1201bcd2 100644
--- a/src/modules/rlm_python3/rlm_python3.c
+++ b/src/modules/rlm_python3/rlm_python3.c
@@ -679,12 +679,10 @@ static rlm_rcode_t do_python_single(REQUEST *request, PyObject *pFunc, char cons
static void python_interpreter_free(PyThreadState *interp)
{
-DIAG_OFF(deprecated-declarations)
- PyEval_AcquireLock();
+ PyEval_RestoreThread(interp);
PyThreadState_Swap(interp);
Py_EndInterpreter(interp);
- PyEval_ReleaseLock();
-DIAG_ON(deprecated-declarations)
+ PyEval_SaveThread();
}
/** Destroy a thread state
@@ -1117,7 +1115,21 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
python_dlhandle = dlopen_libpython(RTLD_NOW | RTLD_GLOBAL);
if (!python_dlhandle) WARN("Failed loading libpython symbols into global symbol table");
-#if PY_VERSION_HEX >= 0x03050000
+#if PY_VERSION_HEX > 0x030a0000
+ PyStatus status;
+
+ PyConfig config;
+ PyConfig_InitIsolatedConfig(&config); /* Isolated config: Don't override signal handlers - noop on subs calls */
+
+ wchar_t *name;
+ MEM(name = Py_DecodeLocale(main_config.name, NULL)); /* The value of argv[0] as a wide char string */
+ status = PyConfig_SetString(&config, &config.program_name, name);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(&config);
+ return -1;
+ }
+ PyMem_RawFree(name);
+#elif PY_VERSION_HEX >= 0x03050000
{
wchar_t *name;
@@ -1134,8 +1146,17 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
}
#endif
+#if PY_VERSION_HEX > 0x030a0000
+ status = Py_InitializeFromConfig(&config);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(&config);
+ return -1;
+ }
+ PyConfig_Clear(&config);
+#else
Py_InitializeEx(0); /* Don't override signal handlers - noop on subs calls */
PyEval_InitThreads(); /* This also grabs a lock (which we then need to release) */
+#endif
main_interpreter = PyThreadState_Get(); /* Store reference to the main interpreter */
locked = true;
}