An easy setup of Visual Studio Code for running your Python Azure Functions on your M/arm64 Mac.

Christian Henrik Reich
5 min readSep 25, 2023

--

The pain

For the first time in a few months, I was creating a new Python Azure Function. Last time i did that was on a Intel based Mac, today it was a on my newer M/arm64 based Mac. A bit unexpected, when running locally, I was faced with errors of Python function workers didn’t support arm64.

Checking the Microsoft documentation, it also says so.

Microsoft is refering to a link a new document, which in my book it is a lesser solution. Because:
1) First of all, It doesn’t work. You can’t duplicate Terminal anymore. A work around is install Term2 or such.
2) When running thing from a Emulated Terminal, all runs slower. Even Visual Studio Code if started from a emulated terminal, will run noticeable slow.

The Solution

Still Microsoft is right, we have to do some Intel(a.k.a. X86_64) emulation. If we then just emulate what is needed, we properly won’t notice it regarding usabillity and performance. Our tool for emulating is Rosetta and is already in our OSX, we often never notice it. The only things we have to emulate with Rosetta, regarding Python Azure Functions, is Python and Azure Function Core Tools.

To sum up, the solution is to install Python and Azure Function Core Tools in X86_64 versions and then run them with X86_64 emulator. Installation can be done manual or with Brew. Brew is the most easy.

Brew

Homebrew or just Brew should be everyones favourite package manager on Mac OSX. The challenge here, is that we have to trick Brew into do X86_64 installations. Brew is targeted the CPU architecture, and if installed on a M/arm64 processor, it will do M/arm64 targeted installations.

A way to trick Brew, is to X86_64 emulate z-shell when installing Brew. I have found the best way is to have a arm64/X86_64 toggle option in my z-shell. It can adding following file in your home dir.

/Users/<your user name>/.zshrc

or

~/.zshrc

It can be opened in your favorite editor (VS Code?). Following lines should be added to the end:

alias arm="env /usr/bin/arch -arm64 /bin/zsh --login"
alias intel="env /usr/bin/arch -x86_64 /bin/zsh --login"

if [ $(arch) = "i386" ]; then
alias brew='/usr/local/bin/brew'
else
alias brew='/opt/homebrew/bin/brew'
fi

I have also added $(arch) to my prompt so I can se which mode I’m in:

Restart Terminal or source ~/.zshrc

What the snippet does is to make an alias, so when ‘intel’ is written in Terminal, it starts a new shell in a Rosetta X86_64 emulated mode. To switch back close it by typing ‘exit’ and not typing ‘arm’, else you end up with a long line of z-shells opening z-shells.

By design, when Brew is installed on a M/arm64 based Mac, it is installed to /opt/homebrew/bin. On an Intel based Mac, Brew is installed to /usr/local/bin. The z-shell snippet makes an alias for Brew, so the environments points to the right Brew.

When running the Brew install one-liner, in a X86_64 z-shell and a M/arm64 z-shell. The one-liner can be found on Brew’s homepage.

The caveats regarding Brew

When packges are installed for M/arm64 and you try to install a package for 86_64, Brew might think the package is already installed for 86_64 as well, and vice versa. If this is the case, just re-install the package in the environment you want it in, even if hasn’t been installed before. Also, installed packages does not get deleted in the different environments. Due to the 2 Brew locations, you can have installation for both architectures.

TL;DR: The VS Code setup

So you only need a X86_64 version of Python and Azure Function Core Tool. Run brew in X86_64 mode with the ‘intel’ alias and install or reinstall the packages:

intel

brew install python@3.10
brew tap azure/functions
brew install azure-functions-core-tools@4

Both packages can be found in /usr/local/opt and /usr/local/cellar

Navigate to VS Code.
I use VS Code to make my Python virtual environment for the Azure Function. A way to recreate it with the X86_64 version of Python, is to delete the .venv file (often located close to you .vscode folder).

When restarting VS Code, it will suggest to create a virtual environment and you can type the full path to the X86_64 Python.

Last, we have toadd a secret property, to our settings.json in the .vscode folder:

"azureFunctions.funcCliPath": "/usr/local/Cellar/azure-functions-core-tools@4/4.0.5348/func"

NB! The version number is properly different for your’s, and will change if upgrade the Azure Function Core Tools.

Now we are ready! Run from the VS Code debugger:

Finally

According to this old github issue, according the contributers it should be fixed soon. Until then, this is a work around.

--

--

Christian Henrik Reich
Christian Henrik Reich

Written by Christian Henrik Reich

Renaissance man @ twoday Kapacity, Renaissance man @ Mugato.com. Focusing on data architecture, ML/AI and backend dev, cloud and on-premise.

No responses yet