Hey everyone,
I just stumbled across this binary: python3.x-intel64 (mentioned here)
I am in a situation where I need to run x86_64 versions of Python. What I normally do, is just start an Rosetta2 terminal (arch -x86_64 zsh) and then run the normal python3.x command (without the -intel64). Does Python automatically recognize that I run it in Rosetta2 or would it be better to explicitly run the python3.x-intel64 binary instead?
Typically macOS apps are shipped as āuniversal2ā which means they have the code for intel and arm CPUs in them.
This is the case of python which is described as āmacOS 64-bit universal2 installerā.
If you are using and old version of python that is intel only then when you run on an arm mac macOS will automatically use rossetta2 to run the app.
As an end user there is nothing you need to do. It should ājust workā.
As a developer you may need to understand the details; especially if you are building binary python modules.
On my apple silicon mac I see what 3.8, 3.9, 3.10, 3.11 and 3.12 are all universal2.
You have to be running an older version then that to have any problems.
I do wonder why there is an explicit python3.X-intel64 image.
The arch command will force the use of x86_64 for you.
When I do arch -x86_64 python3.12 and then check with lsof -p <pid> I see /Library/Apple/usr/libexec/oah/libRosettaRuntime is loaded.
All my pythons (at least those from python.org) are installed from the universal2 installer. Still I was wondering what this eplicit -intel64 binary would do. I havenāt encountered any issues yet, except I was not able to run the Python debugger in Rosetta2 mode in VSCode. Maybe here the binary could be helpful.
I also wonder, why there is an explicit -intel64 binary, but not an explicit -arm64 binary. Since I like to keep things explicit, Iād prefer running those two over letting the arch be detected automatically.
If you know you have a universal2 build, then, yes, it will load the right executable. But Pythons installed by conda for instance may not be universal2, but only arm64 (if you have an M1 or M2), and they run also inside arch -x86_64 zsh (without loading Rosetta of course). Also, people may have an arm64-specific platform Python (my 3.10 one is arm64 only for instance).
I was surprised by this. But I verified using lipo -archs/lipo -info that the conda Pythons are arm64 only. I also wonder what this means when you try to load extension module code specifically compiled for x86_64 - it should really not be possible, I would guess. But simply opening python and importing some standard modules definitely is possibleā¦
In other words, simply running in that zsh does not appear to be enough to ensure youāre running an intel64-compatible binary.
The ānormalā python3 binary in our installers is a Universal 2 binary and should pick up whatever architecture is the default (e.g. should run as x86_64 when in a Rosetta2 terminal).
You can also start Python itself as x86_64 by using āarch -x86_64 python3ā, which is what I primarily use when I want to use Rosetta2. This has a limitation though: it can result in subprocesses running as native arm64 when launching python subprocesses using fork+exec or multiprocessing. The python3-intel64 binary should be save in that respect.
So, if I use python3.x in an arch -x86_64 zsh session, the packages that are installed are at least x86_64 is there any way to check, which arch python is running at directly within python?
Running in an arch -x86_64 zsh shell is not equivalent to running python itself with that option directly
arch -x86_64 python3
The last command is safer to use since it will immediately exit if python3 is not a universal2 but only an arm64 binary while running pyhon3 (only compiled for arm64) in an arch -x86_64 zsh shell will not error - until you try to load intel-only extension module code. Safer yet would be, as you said, to be explicit about it: