cext: use sys.executable instead of deprecated Py_GetProgramFullPath stable
authorMads Kiilerich <mads@kiilerich.com>
Thu, 11 Jan 2024 20:32:07 +0100
branchstable
changeset 52109 5ac506ee6690
parent 52108 c6e4fec01775
child 52110 c5d6a66092e8
cext: use sys.executable instead of deprecated Py_GetProgramFullPath Fix warning with Python 3.13: mercurial/cext/parsers.c: In function 'check_python_version': mercurial/cext/parsers.c:1243:30: warning: 'Py_GetProgramFullPath' is deprecated [-Wdeprecated-declarations] 1243 | Py_GetProgramFullPath()); | ^~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/python3.13/Python.h:119, from mercurial/cext/parsers.c:11: /usr/include/python3.13/pylifecycle.h:43:43: note: declared here 43 | Py_DEPRECATED(3.13) PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void); | ^~~~~~~~~~~~~~~~~~~~~ At this point in time, the PyConfig struct memory has been released and the PyConfig API can't be used. https://docs.python.org/3.13/c-api/init.html#c.Py_GetProgramFullPath recommands using sys.executable instead. Let's assume that will work in all versions. It would perhaps be better to use PySys_GetObject, but I prefer to stay consistent with how the same function is retrieving sys.hexversion.
mercurial/cext/parsers.c
--- a/mercurial/cext/parsers.c	Thu Jan 11 21:58:55 2024 +0100
+++ b/mercurial/cext/parsers.c	Thu Jan 11 20:32:07 2024 +0100
@@ -1232,6 +1232,15 @@
 	 * should only occur in unusual circumstances (e.g. if sys.hexversion
 	 * is manually set to an invalid value). */
 	if ((hexversion == -1) || (hexversion >> 16 != PY_VERSION_HEX >> 16)) {
+		PyObject *sys = PyImport_ImportModule("sys"), *executable;
+		if (!sys) {
+			return -1;
+		}
+		executable = PyObject_GetAttrString(sys, "executable");
+		Py_DECREF(sys);
+		if (!executable) {
+			return -1;
+		}
 		PyErr_Format(PyExc_ImportError,
 		             "%s: The Mercurial extension "
 		             "modules were compiled with Python " PY_VERSION
@@ -1240,7 +1249,8 @@
 		             "sys.hexversion=%ld: "
 		             "Python %s\n at: %s",
 		             versionerrortext, hexversion, Py_GetVersion(),
-		             Py_GetProgramFullPath());
+		             PyUnicode_AsUTF8(executable));
+		Py_DECREF(executable);
 		return -1;
 	}
 	return 0;