virtualenv icon indicating copy to clipboard operation
virtualenv copied to clipboard

CPython2 support for macOS Big Sur

Open glandium opened this issue 4 years ago • 15 comments

Issue

After creating a virtualenv with python2 from the Command Line Tools, running the python executable from that virtualenv fails:

% python virtualenv.pyz venv   
created virtual environment CPython2.7.16.final.0-64 in 221ms
  creator CPython2macOsFramework(dest=/Users/glandium/venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, wheel=bundle, setuptools=bundle, via=copy, app_data_dir=/Users/glandium/Library/Application Support/virtualenv)
    added seed packages: pip==20.2.2, pip==20.2.4, setuptools==44.1.1, wheel==0.35.1
  activators PythonActivator,CShellActivator,FishActivator,PowerShellActivator,BashActivator
% venv/bin/python
zsh: killed     venv/bin/python

The problem comes from code signature not matching:

% codesign -v venv/bin/python
venv/bin/python: invalid Info.plist (plist or signature have been modified)
In architecture: x86_64

This doesn't happen with python3.

glandium avatar Nov 25 '20 23:11 glandium

I actually failed to reproduce on a x86_64 mac, despite the signature not being valid there too. I did originally hit this on an arm64 DTK, and got someone else to reproduce on one of the new M1-based Mac minis, and there appear to be two levels with this:

  • one is the codesign issue, which can be worked around by replacing the signature manually with codesign -s - -f
  • but once the codesign issue is solved, running still fails and now gives the following in the console log: `exec_mach_imgact: not running binary "python" built against preview arm64e ABI"

And indeed, the executable behind sys.executable is a Universal x86_64/arm64e binary for python, but is a Universal x86_64/arm64 binary for python3, thus why there is no problem with python3.

glandium avatar Nov 26 '20 04:11 glandium

Editing create/via_global_ref/builtin/cpython/mac_os.py to always fallback to install_name_tool makes it emit a warning about the first half of the issue:

/Library/Developer/CommandLineTools/usr/bin/install_name_tool: warning: changes being made to the file will invalidate the code signature in: /Users/glandium/venv/bin/python (for architecture x86_64)
/Library/Developer/CommandLineTools/usr/bin/install_name_tool: warning: changes being made to the file will invalidate the code signature in: /Users/glandium/venv/bin/python (for architecture arm64e)

glandium avatar Nov 26 '20 04:11 glandium

FWIW, I confirmed both are independent:

  • After disabling SIP (csrutil disable), the codesign issue doesn't appear (no need to replace the signature), but the arm64e problem still does
  • After enabling the arm64e preview abi (sudo nvram boot-args=-arm64e_preview_abi), the virtualenv python works just fine
  • After re-enabling SIP (csrutil enable), but keeping the arm64e preview abi, it doesn't work anymore.

glandium avatar Nov 26 '20 05:11 glandium

Let's spin out the M1 part into https://github.com/pypa/virtualenv/issues/2024, as for the Big Sur one we can follow it here. It's a new OS/platform so virtualenv not working on them is a feature request rather than a bug one. I don't have at the moment access to Big Sur machine, so can't help with it, so PRs welcome.

gaborbernat avatar Nov 26 '20 15:11 gaborbernat

As mentioned in the second comment, the codesign validity preventing python from running actually doesn't happen on x86_64 based Big Sur, for some reason, although the code signature is invalid.

glandium avatar Nov 26 '20 20:11 glandium

Any way to check if the certificate/whatever had an expiry date or compatibility info that makes it incompatible with Big Sur?

pradyunsg avatar Nov 26 '20 20:11 pradyunsg

The problem is virtualenv is editing the executable to change its dependencies to use @executable_path, invalidating the signature.

glandium avatar Nov 26 '20 20:11 glandium

The problem is without the edit, the executable will not run. Changing that path invalids the signature, but it is the only way we can create a virtual environment. Not sure what else we can do. We could resign it, but for that, you need a key, and we'd not even be the same key, etc. Considering CPython 2 is EOL on macOS, I'd not expect them to offer any solutions for it. @glandium ideas?

gaborbernat avatar Nov 27 '20 09:11 gaborbernat

codesign -s - -f venv/bin/python works, until it doesn't and says the codesign_allocate helper tool cannot be found or used, which I'm not sure under which circumstances it happens (although it seems to involve Rosetta), but it does:

% python virtualenv.pyz venv      
created virtual environment CPython2.7.16.final.0-64 in 192ms
  creator CPython2macOsFramework(dest=/Users/glandium/venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, wheel=bundle, setuptools=bundle, via=copy, app_data_dir=/Users/glandium/Library/Application Support/virtualenv)
    added seed packages: pip==20.2.4, setuptools==44.1.1, wheel==0.35.1
  activators PythonActivator,CShellActivator,FishActivator,PowerShellActivator,BashActivator
% arch --x86_64 venv/bin/python   
zsh: killed     arch --x86_64 venv/bin/python
% codesign -s - -f venv/bin/python
venv/bin/python: replacing existing signature
venv/bin/python: the codesign_allocate helper tool cannot be found or used

Another one:

% arch --x86_64 python virtualenv.pyz venv
created virtual environment CPython2.7.16.final.0-64 in 263ms
  creator CPython2macOsFramework(dest=/Users/glandium/venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, wheel=bundle, setuptools=bundle, via=copy, app_data_dir=/Users/glandium/Library/Application Support/virtualenv)
    added seed packages: pip==20.2.4, setuptools==44.1.1, wheel==0.35.1
  activators PythonActivator,CShellActivator,FishActivator,PowerShellActivator,BashActivator
% venv/bin/python
zsh: killed     venv/bin/python
% codesign -s - -f venv/bin/python        
venv/bin/python: replacing existing signature
venv/bin/python: the codesign_allocate helper tool cannot be found or used

But it doesn't happen here:

% arch --x86_64 python virtualenv.pyz venv
created virtual environment CPython2.7.16.final.0-64 in 263ms
  creator CPython2macOsFramework(dest=/Users/glandium/venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, wheel=bundle, setuptools=bundle, via=copy, app_data_dir=/Users/glandium/Library/Application Support/virtualenv)
    added seed packages: pip==20.2.4, setuptools==44.1.1, wheel==0.35.1
  activators PythonActivator,CShellActivator,FishActivator,PowerShellActivator,BashActivator
% codesign -s - -f venv/bin/python        
venv/bin/python: replacing existing signature

So I guess if virtualenv itself would do the code signing, it would work™.

But the arm64e problem is unsolvable if virtualenv can't be made to work with symbolic links. That said, after codesign -s - -f venv/bin/python succeeds, arch --x86_64 venv/bin/python does work.

It really sucks that the failure mode is that the process is killed rather than a more useful error message directly on the command line (instead of hidden in the console log).

glandium avatar Nov 27 '20 20:11 glandium

But the arm64e problem is unsolvable if virtualenv can't be made to work with symbolic links.

It's not that virtualenv can't be made to work with, but rather there's no way to make the cpython 2 interpreter work with symlinks.

gaborbernat avatar Nov 28 '20 07:11 gaborbernat

Creating a symlink from venv/bin/python to the real python works just fine, but I assume sys.path is not correct (although I haven't compared).

glandium avatar Nov 28 '20 09:11 glandium

Creating a symlink is just a symlink. Will behave exactly as the target python would behave. That's the opposite of what a virtual environment is. Making a virtual environment means ensuring the sys.path is correct, which is much harder.

gaborbernat avatar Nov 28 '20 09:11 gaborbernat

venv/bin/python: replacing existing signature
venv/bin/python: the codesign_allocate helper tool cannot be found or used

I found that codesign would work if you copy in and out the folder once:

cd venv/bin
mkdir bk; cp python bk; mv -f bk/python .;rmdir bk
codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f python

nickwph avatar Dec 20 '20 17:12 nickwph

just installed django 1.8 envs on Apple M1 using virtualenv successed, hope it will help you

https://gist.github.com/MxJ24/e1386c9012f533cfbedfed5114da3e60 https://gist.github.com/MxJ24/19482861156b9b4ef24928f3c49a89f5

MxJ24 avatar Mar 06 '21 03:03 MxJ24

It really sucks that the failure mode is that the process is killed rather than a more useful error message directly on the command line (instead of hidden in the console log).

I totally agree. https://github.com/pypa/virtualenv/pull/2179 will fix at least this.

gdubicki avatar Sep 11 '21 14:09 gdubicki

We no longer support Python 2.

gaborbernat avatar Jun 27 '23 03:06 gaborbernat