[PATCH 6 of 8] cext: use sys.executable instead of deprecated Py_GetProgramFullPath

Mads Kiilerich mads at kiilerich.com
Fri Jul 26 19:42:23 UTC 2024


# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1705001527 -3600
#      Thu Jan 11 20:32:07 2024 +0100
# Node ID 3b18b545b9bf7af5ab97805121fa52b31a319d53
# Parent  60ffa0a3c5806d3e9cbbcb70eebd6a1afbe804d8
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.

diff --git a/mercurial/cext/parsers.c b/mercurial/cext/parsers.c
--- a/mercurial/cext/parsers.c
+++ b/mercurial/cext/parsers.c
@@ -1232,6 +1232,15 @@ static int check_python_version(void)
 	 * 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 @@ static int check_python_version(void)
 		             "sys.hexversion=%ld: "
 		             "Python %s\n at: %s",
 		             versionerrortext, hexversion, Py_GetVersion(),
-		             Py_GetProgramFullPath());
+		             PyUnicode_AsUTF8(executable));
+		Py_DECREF(executable);
 		return -1;
 	}
 	return 0;



More information about the Mercurial-devel mailing list