diff --git a/docs/changelog.rst b/docs/changelog.rst index 787dd1c4..9165dbda 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -21,6 +21,7 @@ To avail of fixes in an unreleased version, please download a ZIP file v0.3.1.dev0 (unreleased) ------------------------ +* :gh:issue:`774` Fix bootstrap failures on macOS 11.x and 12.x, involving Python 2.7 wrapper * :gh:issue:`834` Support for Ansible 3 and 4 (ansible-core 2.11) * :gh:issue:`869` Continuous Integration tests are now run with Tox * :gh:issue:`869` Continuous Integration tests now cover CentOS 6 & 8, Debian 9 & 11, Ubuntu 16.04 & 20.04 diff --git a/mitogen/parent.py b/mitogen/parent.py index 44ff9aba..c3efe28a 100644 --- a/mitogen/parent.py +++ b/mitogen/parent.py @@ -1412,9 +1412,12 @@ class Connection(object): # * macOS <= 10.14 (Darwin <= 18) install an unreliable Python version # switcher as /usr/bin/python, which introspects argv0. To workaround # it we redirect attempts to call /usr/bin/python with an explicit - # call to /usr/bin/python2.7. macOS 10.15+ (Darwin 19+) removed it. - # On these versions /usr/bin/python is a symlink to - # /System/Library/Frameworks/Python.framework/Versions/2.7/.../Python + # call to /usr/bin/python2.7. macOS 10.15 (Darwin 19) removed it. + # * macOS 11.x (Darwin 20, Big Sur) and macOS 12.x (Darwin 21, Montery) + # do something slightly different. The Python executable is patched to + # perform an extra execvp(). I don't fully understand the details, but + # setting PYTHON_LAUNCHED_FROM_WRAPPER=1 avoids it. + # * macOS 13.x (Darwin 22?) may remove python 2.x entirely. # # Locals: # R: read side of interpreter stdin. @@ -1437,7 +1440,8 @@ class Connection(object): os.close(r) os.close(W) os.close(w) - if sys.executable+sys.platform=='/usr/bin/pythondarwin'and os.uname()[2]<'19':sys.executable+='2.7' + if os.uname()[0]=='Darwin'and os.uname()[2][:2]<'19'and sys.executable=='/usr/bin/python':sys.executable='/usr/bin/python2.7' + if os.uname()[0]=='Darwin'and os.uname()[2][:2]in'2021'and sys.version[:3]=='2.7':os.environ['PYTHON_LAUNCHED_FROM_WRAPPER']='1' os.environ['ARGV0']=sys.executable os.execl(sys.executable,sys.executable+'(mitogen:CONTEXT_NAME)') os.write(1,'MITO000\n'.encode())