Skip to content

Commit f6b631d

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

File tree

2 files changed

+113
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)