<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-ports.
</pre>
<p><a href="https://github.com/macports/macports-ports/commit/cb9bdc4754f0dcd232858255a94210a4ee4203e8">https://github.com/macports/macports-ports/commit/cb9bdc4754f0dcd232858255a94210a4ee4203e8</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new cb9bdc4754f python27: fix support for virtualenv on macOS 12 (#13480)
</span>cb9bdc4754f is described below
<span style='display:block; white-space:pre;color:#808000;'>commit cb9bdc4754f0dcd232858255a94210a4ee4203e8
</span>Author: Thomas Buchberger <thomas.buchberger@gmail.com>
AuthorDate: Fri Jan 7 19:34:47 2022 +0100
<span style='display:block; white-space:pre;color:#404040;'> python27: fix support for virtualenv on macOS 12 (#13480)
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> On macOS 12 (Monterey), dladdr, NSLibraryNameForModule and similar
</span><span style='display:block; white-space:pre;color:#404040;'> functions return the real path of the dynamic library instead of the
</span><span style='display:block; white-space:pre;color:#404040;'> path to the symlink in a virtualenv. This breaks support for virtualenv.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> By applying the same patch as Apple does for its Python version, which
</span><span style='display:block; white-space:pre;color:#404040;'> avoids using these functions whenever possible, support for virtualenv
</span><span style='display:block; white-space:pre;color:#404040;'> is restored.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> See also:
</span><span style='display:block; white-space:pre;color:#404040;'> https://github.com/apple-oss-distributions/python/blob/python-136.120.2/2.7/fix/getpath.c.ed
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> Co-authored-by: Joshua Root <jmr@macports.org>
</span>---
lang/python27/Portfile | 7 ++-
lang/python27/files/patch-getpath.diff | 82 ++++++++++++++++++++++++++++++++++
2 files changed, 87 insertions(+), 2 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/lang/python27/Portfile b/lang/python27/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index 831ffa5fb45..ce1c2052b7e 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/lang/python27/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/lang/python27/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -9,7 +9,7 @@ name python27
</span> epoch 2
# Remember to keep py27-tkinter and py27-gdbm's versions sync'd with this
version 2.7.18
<span style='display:block; white-space:pre;background:#ffe0e0;'>-revision 5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision 7
</span>
set major [lindex [split $version .] 0]
set branch [join [lrange [split ${version} .] 0 1] .]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -47,6 +47,10 @@ patchfiles patch-Makefile.pre.in.diff \
</span> implicit.patch \
openssl_ver.patch
<span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${os.platform} eq "darwin" && ${os.major} >= 21} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ patchfiles-append patch-getpath.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> depends_build port:pkgconfig
depends_lib port:bzip2 \
port:db48 \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -64,7 +68,6 @@ openssl.branch 1.1
</span>
# This port is used by clang-3.4 to bootstrap libcxx
subport ${name}-bootstrap {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- revision 6
</span> set stdprefix ${prefix}
prefix ${prefix}/libexec/libcxx-bootstrap
set frameworks_dir ${prefix}/Library/Frameworks
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/lang/python27/files/patch-getpath.diff b/lang/python27/files/patch-getpath.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..c1dbe2ecfed
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/lang/python27/files/patch-getpath.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,82 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+As of macOS 12, dladdr, NSLibraryNameForModule, and similar functions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+will resolve symlinks, which breaks virtualenv. This works around that
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+issue by not using those functions if at all possible.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Adapted from https://github.com/apple-oss-distributions/python/blob/python-136.120.2/2.7/fix/getpath.c.ed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- Modules/getpath.c.orig 2022-01-08 05:08:48.000000000 +1100
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ Modules/getpath.c 2022-01-08 05:13:34.000000000 +1100
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -7,7 +7,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <string.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include <mach-o/dyld.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <dlfcn.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <AvailabilityMacros.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -380,9 +380,10 @@ calculate_path(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ size_t prefixsz;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *defpath = pythonpath;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef WITH_NEXT_FRAMEWORK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- NSModule pythonModule;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Dl_info addrinfo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int first_pass = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uint32_t nsexeclength = MAXPATHLEN;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -397,7 +398,7 @@ calculate_path(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (strchr(prog, SEP))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ strncpy(progpath, prog, MAXPATHLEN);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#ifdef __APPLE__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* On Mac OS X, if a script uses an interpreter of the form
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * "#!/opt/python2.3/bin/python", the kernel only passes "python"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * as argv[0], which falls through to the $PATH search below.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -410,7 +411,7 @@ calculate_path(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#endif /* __APPLE__ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif /* notdef */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (path) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ while (1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *delim = strchr(path, DELIM);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -449,9 +450,18 @@ calculate_path(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ** which is in the framework, not relative to the executable, which ma
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ** be outside of the framework. Except when we're in the build directory...
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- /* Use dylib functions to find out where the framework was loaded from */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- buf = (char *)NSLibraryNameForModule(pythonModule);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* dladdr() now returns the real path of the dylib, instead of the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ** path of the symlink. This breaks virtualenv. To fix this, we
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ** skip using dladdr() during a first pass, and if that fails, then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ** we go back and do the dladdr(). It turns out that since we moved
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ** Python.app to inside the Python.framework bundle, the call to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ** search_for_prefix() will now succeed without needing dladdr().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ** However, virtualenv copies the wrong binary when the prefix is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ** /usr, so if progpath begins with /usr/bin/, we skip the first pass.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (strncmp(progpath, "/usr/bin/", 9) == 0) first_pass = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++return_here_for_second_pass:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ buf = first_pass ? NULL : (dladdr("_Py_Initialize", &addrinfo) ? (char *)addrinfo.dli_fname : NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (buf != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* We're in a framework. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* See if we might be in the build directory. The framework in the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -504,6 +514,12 @@ calculate_path(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!(pfound = search_for_prefix(argv0_path, home))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef WITH_NEXT_FRAMEWORK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (first_pass) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ first_pass = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ goto return_here_for_second_pass;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!Py_FrozenFlag)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "Could not find platform independent libraries <prefix>\n");
</span></pre><pre style='margin:0'>
</pre>