Python 3.9.1 adds a universal2 build for Apple Silicon
Python 3.9.1 supports macOS 11 and a binary containing arm64 and x86_64 code. The new interpreter build also requires the surrounding installation tools to recognise its platform.
A new processor architecture changes more than the executable that starts an interpreter. Build configuration and package tooling also need to describe which code can run. Python 3.9.1, released December 7, adds support for macOS 11 Big Sur and a universal2 installer that can run on Apple Silicon. The release calls that installer experimental while waiting for an updated pip.
That qualification makes the release interesting. Having an interpreter for the architecture is a necessary part of the transition, but package installation must also understand the resulting platform. The interpreter and its packaging tools have related responsibilities that can reach readiness at different times.
I often choose Python because of libraries whose native components implement the expensive work. That makes architecture support an ecosystem question for me. Starting a Python process and obtaining an appropriate build of a native dependency are separate capabilities.
Universal2 contains two architectures
The macOS build guide in the release source defines a universal binary as one executable or library containing object code for more than one CPU architecture. Its architecture list identifies universal2 as the combination of arm64 and x86_64. This is a concrete binary format choice, not a change to the semantics of a Python source file.
The guide documents several universal build combinations because this is an existing macOS build mechanism. Universal2 selects a particular pair. The distinction matters when reading older configuration names. The guide's intel combination means i386 and x86_64, so it does not mean the new Apple Silicon and Intel pair.
For a builder, naming the intended architecture set explicitly prevents that ambiguity. The maintenance notes supply the configuration options for the new combination.
./configure --enable-universalsdk --with-universal-archs=universal2
This is the configuration step for an appropriate macOS build environment. It is not a complete installation recipe or a promise that an arbitrary installed SDK supports the requested architectures. The same notes record new checks that the specified architectures can actually be used.
The SDK and deployment target are different inputs
The macOS guide explains that the universal SDK option can accept an SDK path. Without an explicit path, the active Xcode or Command Line Tools developer directory supplies the default SDK. Modern macOS development places system headers in an SDK, so assuming that headers are installed in their old filesystem locations is inadequate.
The maintenance notes also distinguish the machine used to build an artifact from the systems on which it can be deployed. They describe binaries built on newer macOS versions running on older versions when the deployment target is correct. This work was tested with Xcode 11 and later, with deployment testing down to macOS 10.9.
That does not mean every architecture in a universal binary executes on every deployment system. The artifact includes architecture-specific code. The useful property is that one distributed file can contain code appropriate to different supported machines, while its build still needs compatible SDK and deployment settings.
Platform naming has to represent the combination
The released macOS platform-support code recognises the architecture pair when constructing platform information. It extracts -arch values from compiler flags, removes duplicates, and sorts them. When that set is arm64 and x86_64, it assigns the machine label universal2.
This shows why adding compiler support alone is insufficient. Code describing the build needs a name for the combined artifact. A single-architecture label would lose information about the other architecture, while an older universal label could describe a different pair entirely.
The installer warning on the release page belongs to that broader integration problem. It says to treat the new installer as experimental pending a pip update. That is a specific statement about the tools available with this release, not evidence that the language changes its behaviour on every Apple Silicon program.
I prefer the explicit qualification because it describes what is ready and where work remains. A runtime can support a machine while a package installation workflow still needs an update. Calling the entire transition complete would hide that practical distinction.
Applications inherit the architecture of their native components
Python's universal build guide discusses executables and libraries together. The same distinction is useful when thinking about a Python application with native dependencies. A source module and a compiled library are different artifacts, so the presence of one cannot establish the availability of the other for a selected architecture.
The application-level implication is to identify which artifacts carry native code and how the build describes them. That follows from the universal binary's architecture-specific contents. It does not require assuming that a particular third-party package already supplies a compatible release.
Python 3.9.1 provides the interpreter build option and the platform label for the new pair. Its macOS notes also record work allowing distutils to find system-provided libraries on macOS 11. Those changes make the platform usable through several parts of the build and installation process, while the experimental installer qualification remains part of the release's published contract.