Skip to content

Commit 43739ac

Browse files
committed
Short-term getpath fix
1 parent 642c300 commit 43739ac

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

cpython-unix/build-cpython.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,11 @@ if [ -n "${CROSS_COMPILING}" ]; then
629629
# TODO: There are probably more of these, see #599.
630630
fi
631631

632+
# TODO description
633+
if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]]; then
634+
patch -p1 -i "${ROOT}/patch-python-getpath-3.14.patch"
635+
fi
636+
632637
# We patched configure.ac above. Reflect those changes.
633638
autoconf
634639

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
From 4c69b0e246bd1057f640f87dfa5937a032f32f83 Mon Sep 17 00:00:00 2001
2+
From: Geoffrey Thomas <[email protected]>
3+
Date: Mon, 1 Dec 2025 14:11:43 -0500
4+
Subject: [PATCH 1/1] getpath: Fix library detection and canonicalize paths
5+
6+
TODO description
7+
---
8+
Modules/getpath.c | 43 +++++++++++++++++++++++++++++++++++++------
9+
Modules/getpath.py | 4 ++--
10+
2 files changed, 39 insertions(+), 8 deletions(-)
11+
12+
diff --git a/Modules/getpath.c b/Modules/getpath.c
13+
index 1e75993480a..f8fc1608de4 100644
14+
--- a/Modules/getpath.c
15+
+++ b/Modules/getpath.c
16+
@@ -802,14 +802,16 @@ progname_to_dict(PyObject *dict, const char *key)
17+
}
18+
19+
20+
+static void
21+
+fclose_cleanup(FILE **pf) {
22+
+ fclose(*pf);
23+
+}
24+
+
25+
+
26+
/* Add the runtime library's path to the dict */
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+
@@ -817,12 +819,41 @@ library_to_dict(PyObject *dict, const char *key)
38+
}
39+
#endif
40+
41+
+ const void *target = (void *)Py_Initialize;
42+
+
43+
+#ifdef __linux__
44+
+ /* Linux libcs do not reliably report the canonical path in dli_fname, but
45+
+ * we have /proc/self/maps. (dyld seems to reliably report the canonical
46+
+ * path, so this matches the behavior on macOS.) */
47+
+
48+
+ FILE *maps __attribute__((cleanup(fclose_cleanup))) = fopen("/proc/self/maps", "r");
49+
+ if (maps != NULL) {
50+
+ /* Format is documented in proc_pid_maps(5), but you want to look at
51+
+ * the implementation in fs/proc/task_mmu.c for spacing. The pathname
52+
+ * is the last field and has any \n characters escaped, so we can read
53+
+ * until \n. Note that the filename may have " (deleted)" appended;
54+
+ * we don't bother to handle that specially as the one user of this
55+
+ * value calls dirname() anyway.
56+
+ * TODO(geofft): Consider using PROCMAP_QUERY if supported.
57+
+ */
58+
+ uintptr_t low, high;
59+
+ char filename[PATH_MAX];
60+
+ while (fscanf(maps, "%lx-%lx %*s %*s %*s %*s %[^\n]", &low, &high, filename) == 3) {
61+
+ if (low <= (uintptr_t)target && (uintptr_t)target < high) {
62+
+ if (filename[0] == '/') {
63+
+ return decode_to_dict(dict, key, filename);
64+
+ }
65+
+ break;
66+
+ }
67+
+ }
68+
+ }
69+
+#endif
70+
+
71+
#if HAVE_DLADDR
72+
Dl_info libpython_info;
73+
- if (dladdr(&Py_Initialize, &libpython_info) && libpython_info.dli_fname) {
74+
+ if (dladdr(target, &libpython_info) && libpython_info.dli_fname) {
75+
return decode_to_dict(dict, key, libpython_info.dli_fname);
76+
}
77+
-#endif
78+
#endif
79+
80+
return PyDict_SetItemString(dict, key, Py_None) == 0;
81+
diff --git a/Modules/getpath.py b/Modules/getpath.py
82+
index b89d7427e3f..8c431e53be2 100644
83+
--- a/Modules/getpath.py
84+
+++ b/Modules/getpath.py
85+
@@ -436,7 +436,7 @@ def search_up(prefix, *landmarks, test=isfile):
86+
87+
if not executable_dir and os_name == 'darwin' and library:
88+
# QUIRK: macOS checks adjacent to its library early
89+
- library_dir = dirname(library)
90+
+ library_dir = dirname(dirname(library))
91+
if any(isfile(joinpath(library_dir, p)) for p in STDLIB_LANDMARKS):
92+
# Exceptions here should abort the whole process (to match
93+
# previous behavior)
94+
@@ -570,7 +570,7 @@ def search_up(prefix, *landmarks, test=isfile):
95+
96+
# First try to detect prefix by looking alongside our runtime library, if known
97+
if library and not prefix:
98+
- library_dir = dirname(library)
99+
+ library_dir = dirname(dirname(library))
100+
if ZIP_LANDMARK:
101+
if os_name == 'nt':
102+
# QUIRK: Windows does not search up for ZIP file
103+
--
104+
2.50.1 (Apple Git-155)
105+

0 commit comments

Comments
 (0)