Skip to content

Commit 05d236a

Browse files
committed
Apply the getpath library name patch to 3.11+
Backport the changes to library_to_dict() (the function we're patching in 3.14) in Modules/getpath.c with the help of git checkout -p v3.14.0 -- Modules/getpath.c
1 parent 2b04093 commit 05d236a

File tree

6 files changed

+249
-5
lines changed

6 files changed

+249
-5
lines changed

cpython-unix/build-cpython.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,12 @@ fi
623623
# Adjust the Python startup logic (getpath.py) to properly locate the installation, even when
624624
# invoked through a symlink or through an incorrect argv[0]. Because this Python is relocatable, we
625625
# don't get to rely on the fallback to the compiled-in installation prefix.
626-
if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]]; then
627-
patch -p1 -i "${ROOT}/patch-python-getpath-3.14.patch"
626+
if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_11}" ]]; then
627+
if [ -e "${ROOT}/patch-python-getpath-backport-${PYTHON_MAJMIN_VERSION}.patch" ]; then
628+
# Sync the getpath logic in older minor releases to the current version.
629+
patch -p1 -i "${ROOT}/patch-python-getpath-backport-${PYTHON_MAJMIN_VERSION}.patch"
630+
fi
631+
patch -p1 -i "${ROOT}/patch-python-getpath-library.patch"
628632
fi
629633

630634
# Another, similar change to getpath: When reading inside a venv use the base_executable path to
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
From 8ae511bb9311220b7b9a244c0ae8a7fc44f4c6f4 Mon Sep 17 00:00:00 2001
2+
From: Geoffrey Thomas <geofft@ldpreload.com>
3+
Date: Tue, 16 Dec 2025 09:33:06 -0500
4+
Subject: [PATCH 1/1] Backport relevant parts of 3.14 getpath.c to 3.11
5+
Forwarded: not-needed
6+
7+
---
8+
Modules/getpath.c | 42 ++++++++++++++++--------------------------
9+
1 file changed, 16 insertions(+), 26 deletions(-)
10+
11+
diff --git a/Modules/getpath.c b/Modules/getpath.c
12+
index 61d654065fd..7457f70109f 100644
13+
--- a/Modules/getpath.c
14+
+++ b/Modules/getpath.c
15+
@@ -18,6 +18,10 @@
16+
# include <mach-o/dyld.h>
17+
#endif
18+
19+
+#ifdef HAVE_DLFCN_H
20+
+# include <dlfcn.h>
21+
+#endif
22+
+
23+
/* Reference the precompiled getpath.py */
24+
#include "../Python/frozen_modules/getpath.h"
25+
26+
@@ -762,39 +766,25 @@ progname_to_dict(PyObject *dict, const char *key)
27+
static int
28+
library_to_dict(PyObject *dict, const char *key)
29+
{
30+
+/* macOS framework builds do not link against a libpython dynamic library, but
31+
+ instead link against a macOS Framework. */
32+
+#if defined(Py_ENABLE_SHARED) || defined(WITH_NEXT_FRAMEWORK)
33+
+
34+
#ifdef MS_WINDOWS
35+
extern HMODULE PyWin_DLLhModule;
36+
if (PyWin_DLLhModule) {
37+
return winmodule_to_dict(dict, key, PyWin_DLLhModule);
38+
}
39+
-#elif defined(WITH_NEXT_FRAMEWORK)
40+
- static char modPath[MAXPATHLEN + 1];
41+
- static int modPathInitialized = -1;
42+
- if (modPathInitialized < 0) {
43+
- modPathInitialized = 0;
44+
-
45+
- /* On Mac OS X we have a special case if we're running from a framework.
46+
- This is because the python home should be set relative to the library,
47+
- which is in the framework, not relative to the executable, which may
48+
- be outside of the framework. Except when we're in the build
49+
- directory... */
50+
- NSSymbol symbol = NSLookupAndBindSymbol("_Py_Initialize");
51+
- if (symbol != NULL) {
52+
- NSModule pythonModule = NSModuleForSymbol(symbol);
53+
- if (pythonModule != NULL) {
54+
- /* Use dylib functions to find out where the framework was loaded from */
55+
- const char *path = NSLibraryNameForModule(pythonModule);
56+
- if (path) {
57+
- strncpy(modPath, path, MAXPATHLEN);
58+
- modPathInitialized = 1;
59+
- }
60+
- }
61+
- }
62+
- }
63+
- if (modPathInitialized > 0) {
64+
- return decode_to_dict(dict, key, modPath);
65+
+#endif
66+
+
67+
+#if HAVE_DLADDR
68+
+ Dl_info libpython_info;
69+
+ if (dladdr(&Py_Initialize, &libpython_info) && libpython_info.dli_fname) {
70+
+ return decode_to_dict(dict, key, libpython_info.dli_fname);
71+
}
72+
#endif
73+
+#endif
74+
+
75+
return PyDict_SetItemString(dict, key, Py_None) == 0;
76+
}
77+
78+
--
79+
2.50.1 (Apple Git-155)
80+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
From f68866fdaedf0e6075300d7809af370f08d2eb8a Mon Sep 17 00:00:00 2001
2+
From: Geoffrey Thomas <geofft@ldpreload.com>
3+
Date: Tue, 16 Dec 2025 09:32:12 -0500
4+
Subject: [PATCH 1/1] Backport relevant parts of 3.14 getpath.c to 3.12
5+
Forwarded: not-needed
6+
7+
---
8+
Modules/getpath.c | 42 +++++++++++++++---------------------------
9+
1 file changed, 15 insertions(+), 27 deletions(-)
10+
11+
diff --git a/Modules/getpath.c b/Modules/getpath.c
12+
index 0a310000751..9cea2d7bd20 100644
13+
--- a/Modules/getpath.c
14+
+++ b/Modules/getpath.c
15+
@@ -18,6 +18,10 @@
16+
# include <mach-o/dyld.h>
17+
#endif
18+
19+
+#ifdef HAVE_DLFCN_H
20+
+# include <dlfcn.h>
21+
+#endif
22+
+
23+
/* Reference the precompiled getpath.py */
24+
#include "../Python/frozen_modules/getpath.h"
25+
26+
@@ -752,41 +756,25 @@ progname_to_dict(PyObject *dict, const char *key)
27+
static int
28+
library_to_dict(PyObject *dict, const char *key)
29+
{
30+
+/* macOS framework builds do not link against a libpython dynamic library, but
31+
+ instead link against a macOS Framework. */
32+
+#if defined(Py_ENABLE_SHARED) || defined(WITH_NEXT_FRAMEWORK)
33+
+
34+
#ifdef MS_WINDOWS
35+
-#ifdef Py_ENABLE_SHARED
36+
extern HMODULE PyWin_DLLhModule;
37+
if (PyWin_DLLhModule) {
38+
return winmodule_to_dict(dict, key, PyWin_DLLhModule);
39+
}
40+
#endif
41+
-#elif defined(WITH_NEXT_FRAMEWORK)
42+
- static char modPath[MAXPATHLEN + 1];
43+
- static int modPathInitialized = -1;
44+
- if (modPathInitialized < 0) {
45+
- modPathInitialized = 0;
46+
-
47+
- /* On Mac OS X we have a special case if we're running from a framework.
48+
- This is because the python home should be set relative to the library,
49+
- which is in the framework, not relative to the executable, which may
50+
- be outside of the framework. Except when we're in the build
51+
- directory... */
52+
- NSSymbol symbol = NSLookupAndBindSymbol("_Py_Initialize");
53+
- if (symbol != NULL) {
54+
- NSModule pythonModule = NSModuleForSymbol(symbol);
55+
- if (pythonModule != NULL) {
56+
- /* Use dylib functions to find out where the framework was loaded from */
57+
- const char *path = NSLibraryNameForModule(pythonModule);
58+
- if (path) {
59+
- strncpy(modPath, path, MAXPATHLEN);
60+
- modPathInitialized = 1;
61+
- }
62+
- }
63+
- }
64+
- }
65+
- if (modPathInitialized > 0) {
66+
- return decode_to_dict(dict, key, modPath);
67+
+
68+
+#if HAVE_DLADDR
69+
+ Dl_info libpython_info;
70+
+ if (dladdr(&Py_Initialize, &libpython_info) && libpython_info.dli_fname) {
71+
+ return decode_to_dict(dict, key, libpython_info.dli_fname);
72+
}
73+
#endif
74+
+#endif
75+
+
76+
return PyDict_SetItemString(dict, key, Py_None) == 0;
77+
}
78+
79+
--
80+
2.50.1 (Apple Git-155)
81+
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
From 97d1e5571392149ba8b19a9aaed6d8eb21978187 Mon Sep 17 00:00:00 2001
2+
From: Geoffrey Thomas <geofft@ldpreload.com>
3+
Date: Tue, 16 Dec 2025 09:29:55 -0500
4+
Subject: [PATCH 1/1] Backport relevant parts of 3.14 getpath.c to 3.13
5+
Forwarded: not-needed
6+
7+
---
8+
Modules/getpath.c | 38 +++++++++++++++-----------------------
9+
1 file changed, 15 insertions(+), 23 deletions(-)
10+
11+
diff --git a/Modules/getpath.c b/Modules/getpath.c
12+
index d0128b20fae..50612432027 100644
13+
--- a/Modules/getpath.c
14+
+++ b/Modules/getpath.c
15+
@@ -17,10 +17,13 @@
16+
#endif
17+
18+
#ifdef __APPLE__
19+
-# include <dlfcn.h>
20+
# include <mach-o/dyld.h>
21+
#endif
22+
23+
+#ifdef HAVE_DLFCN_H
24+
+# include <dlfcn.h>
25+
+#endif
26+
+
27+
/* Reference the precompiled getpath.py */
28+
#include "Python/frozen_modules/getpath.h"
29+
30+
@@ -803,36 +806,25 @@ progname_to_dict(PyObject *dict, const char *key)
31+
static int
32+
library_to_dict(PyObject *dict, const char *key)
33+
{
34+
+/* macOS framework builds do not link against a libpython dynamic library, but
35+
+ instead link against a macOS Framework. */
36+
+#if defined(Py_ENABLE_SHARED) || defined(WITH_NEXT_FRAMEWORK)
37+
+
38+
#ifdef MS_WINDOWS
39+
-#ifdef Py_ENABLE_SHARED
40+
extern HMODULE PyWin_DLLhModule;
41+
if (PyWin_DLLhModule) {
42+
return winmodule_to_dict(dict, key, PyWin_DLLhModule);
43+
}
44+
#endif
45+
-#elif defined(WITH_NEXT_FRAMEWORK)
46+
- static char modPath[MAXPATHLEN + 1];
47+
- static int modPathInitialized = -1;
48+
- if (modPathInitialized < 0) {
49+
- modPathInitialized = 0;
50+
-
51+
- /* On Mac OS X we have a special case if we're running from a framework.
52+
- This is because the python home should be set relative to the library,
53+
- which is in the framework, not relative to the executable, which may
54+
- be outside of the framework. Except when we're in the build
55+
- directory... */
56+
- Dl_info pythonInfo;
57+
- if (dladdr(&Py_Initialize, &pythonInfo)) {
58+
- if (pythonInfo.dli_fname) {
59+
- strncpy(modPath, pythonInfo.dli_fname, MAXPATHLEN);
60+
- modPathInitialized = 1;
61+
- }
62+
- }
63+
- }
64+
- if (modPathInitialized > 0) {
65+
- return decode_to_dict(dict, key, modPath);
66+
+
67+
+#if HAVE_DLADDR
68+
+ Dl_info libpython_info;
69+
+ if (dladdr(&Py_Initialize, &libpython_info) && libpython_info.dli_fname) {
70+
+ return decode_to_dict(dict, key, libpython_info.dli_fname);
71+
}
72+
#endif
73+
+#endif
74+
+
75+
return PyDict_SetItemString(dict, key, Py_None) == 0;
76+
}
77+
78+
--
79+
2.50.1 (Apple Git-155)
80+
File renamed without changes.

src/verify_distribution.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,8 @@ def assertPythonWorks(path: Path, argv0: str = None):
300300
)
301301
assertPythonWorks(venv / "bin" / "python")
302302

303-
if sys.version_info[:2] >= (3, 14):
304-
with self.subTest(msg="weird argv[0]"):
305-
assertPythonWorks(sys.executable, argv0="/dev/null")
303+
with self.subTest(msg="weird argv[0]"):
304+
assertPythonWorks(sys.executable, argv0="/dev/null")
306305

307306

308307
if __name__ == "__main__":

0 commit comments

Comments
 (0)