Python Macos Catalina

This is just to highlight that the Anaconda Python Distribution does not work with the latest MacOS Catalina. I only realized upon trying to open Anaconda Navigator, after installing Catalina. The only (good) solution seems to be reinstalling Anaconda. MacOS Catalina was released on October 7, 2019, and has been causing quite a stir for. Python on a Macintosh running Mac OS X is in principle very similar to Python on any other Unix platform, but there are a number of additional features such as the IDE and the Package Manager that are worth pointing out. Getting and Installing MacPython ¶. Mac OS X 10.8 comes with Python 2.7 pre-installed by Apple. I am experiencing a Python menu issue on both of my Mac's. One Mac has macOS Catalina and Python 3.7.4 via pyEnv with Tcl/Tk 8.6.9 and the other has macOS Catalina and Python 3.8.0. Via pyEnv and Tcl/Tk 8.6.9 and both area exhibiting the same behavior. This behavior did not exist before upgrading from macOS Mojave to macOS Catalina.

Doing it Right¶. Let’s install a real version of Python. Before installing Python, you’ll need to install GCC. GCC can be obtained by downloading Xcode, the smaller Command Line Tools (must have an Apple account) or the even smaller OSX-GCC-Installer package. Install Anaconda (Python 3.7) on Mac OSX Catalina. Nonthakon Jitchiranant.

Python has an amazingly rich ecosystem of libraries, tools and frameworks. It is a clean, modern language, it allowsfor rapid prototyping and quick development cycles. UI was not the central, focal point of my app, so it made a lotof sense for me to do it in Python: I thought I’d write the core functionality first, and add the UI afterwards.

MacOS Catalina (released in 2019) still does not have Python 3 installed by default, only Python 2. Therefore, I neededa way to package the whole application into an app bundle and not make it dependent on user’s Python installation.There are several tools that help with that: py2app,briefcase, pyinstaller. I decided to usePyInstaller, it’s mature, flexible, and offers more customization than the other options.

Step 1: PyInstaller spec file

PyInstaller can be driven by command-line options alone, but that works well for the simplest cases only, and packagingany non-trivial app is not one of these. I suggest running it with command-line parameters, which creates the spec filewith the default values, and then modifying the spec file to suit your needs better. For example, to set the bundleversion to the same value as the application version, and to add some custom plist values:

Step 2: Build the App

This is as simple as

My Application.app will be created, which you can (and should) test to make sure it actually works. Some Pythonpackages require tweaks in PyInstaller spec file: including extra data files in the bundle, etc.

Step 3: Sign the App

In order to be able to notarize it, you must use the hardened run-time.The Hardened Runtime doesn’t affect the operation of most apps, but it does disallow certain capabilities. For Pythonapplications specifically, we need to allow unsigned executable memory. If your app relies on any other capabilitythat the Hardened Runtime restricts, add an entitlement to disable that individual protection as well.

Add entitlements.plist to your project’s root:

And now we’re ready to sign:

Note that in order to be able to notarize the app, you need to sign it with your Apple Developer IDcertificate. Adjust the “Developer” above to match your certificate name, if needed.

Apple recommends to not “deep-sign”, but in this case it’s actually required as all the bundled Python libraries doneed to be signed, not just your main binary.

By adding the --timestamp parameter we include a secure timestamp with the code-signing signature. This is arequirement for notarization.

By adding the entitlements file and passing a -o runtime parameter we enable the hardened runtime, which is alsoa requirement for notarization.

Step 3: Notarize the App

In order to be able to notarize the app,you need to satisfy some additional requirements:

  • All the binaries in the application must be linked against macOS 10.9 or later SDK. If you just re-built everythingwith a recent Xcode, this requirement would be satisfied. If, however, you’re packaging some Python dependency witha pre-built binary extension, it might be built against an older SDK. In this case, you’ll need to build this specificpackage from source.

  • Do not include entitlements that are specifically prohibited. At the time of this writing it’s just onecom.apple.security.get-task-allow entitlement.

Store Apple credentials in the keychain

In order to notarize the app, altool must be able to access Apple APIs on your behalf. To secure this access,store your Apple account credentials in the keychain:

Notarize it!

Since altool expects a Zip archive and not a bare .app directory, create a Zip file first and then notarize it:.

Python

Now you need to wait for the notarization results. You’ll get an email from Apple once it’s complete, stating eithera success or failure (and linking to the error logs in this case).

Step 4: Staple the App

In the notarization step above, Apple has created a “ticket”, which is basically a database record which matches yourapp’s signature and saying that it’s been notarized. Your binary has not been modified in any way. When MacOS runsthis app, it will contact Apple servers and ask for a ticket. If such a ticket exists, the app is deemed “notarized”This will happen only once, and then MacOS will cache the results.

If we want to speed up this initial application execution, or if we want to be able to run it when offline, we need to“staple this ticket to the app”, which downloads the ticket and attaches it to your binary. This is as simple as:

This step is optional, but it must be run only after you received an email from Apple stating that the notarizationwas successful.

Step 5: Verify

Now is the good time to verify that everything is in order:

This command uses Gatekeeper directly to assess whether the application is correctly signed and notarized. It shouldreport:

Conclusion

While the process outlined above works today, it is certainly cumbersome and has some downsides:

  • The development and build process is much more complicated than the normal MacOS development process with Xcode.Getting new developers onboard would be tricky.

  • It is hard to control the libraries that are being pulled in into your app. If some of the dependencies were builtwith Homebrew, the application probably won’t work on MacOS versions older than the build machine.

In my opinion, writing MacOS applications in Python is an acceptable route for prototyping, or for building simplein-house tools quickly, and even notarizing the app is perfectly doable.

Intro¶

Using and developing with Python on MacOS sometimes may be frustrating...

The reason for that is that MacOS uses Python 2 for its core system with pip as a package manager. When Xcode Command Line Tools are installed Python 3 and pip3 package manager will be available at the cli. When using Python2, Python3 and their package managers this way, all the packages will be installed at the system level and my effect the native packages and their dependences , this can break or lead to unwanted bugs in OS.

The right way to use python at MacOS is to use Virtual Environments for python. This way all the system related versions of python and their packages won't be affected and use by you.

Installing and configuring pyenv, pyenv-virtualenv¶

In order to use pyenv, pyenv-virtualenv without conflicting with the native MacOS python we need to add some configuration to our ~/.zshrc config (for mac os catalina) or your bash config if you are still using bash.

It's very imported to maintain the order of the configuration for the loading order

  • First of all we need to include your Executable Paths. In the example we added all the common paths, including the paths for pyenv, pyenv-virtualenv. If you have any other path that you use, you can add them at the same line or create a new line below this one.
  • Second to Executable Paths we will add two if statements that will check if the pyenv,pyenv-virtualenv are installed, if they are it will load them. If they aren't and you are using the same zsh or bash config it will ignore loading them
  • Third is a fix for brew, brew doctor. When using this method it may conflict with brew as it uses python as well. If you run run brew doctor without the fix, it will show config warnings related to the python configuration files.

Configuration for ~/.zshrc or ~/.zprofile

After you saved your configuration the best way to load it is to close your terminal session and open it again. This will load the session with your updated configuration. There should be no errors at the new session.

This will install both pyenv and pyenv-virtualenv

Test if pyenv loaded currently

After the installation we would like to set a system level python version, you can chose the default from the list available from the pyenv

List available Python Version and find the version suited for your needs:

Install Requeued Python Version (Exmaple version 3.9.5) as a default system

Python Idle Macos Catalina

Set it as global

You can install multiply versions of python at the same time.

List all installed python versions and virtual environments and their python versions

Now let's test our system Python version we set before, it should be the version you choose as Global before

So far we cleaned your system and installed and configured pyenv, pyenv-virtualenv.

Install Python Macos Catalina

How to use pyenv-virtualenv¶

Now let's understand how to use Python Virtual Environment with pyenv-virtualenv

Full documentation can be found at the original repo at git hub: pyenv-virtualenv github

We will list here some basic examples for a quick start and basic understanding

To create a virtualenv for the Python version used with pyenv, run pyenv virtualenv, specifying the Python version you want and the name of the virtualenv directory. For example,

This will create a virtualenv based on Python 3.9.5 under $(pyenv root)/versions in a folder called my-project-name

Python 2.7 Macos Catalina

Activating virtualenv automatically for project

Macos Catalina Python 3

The best way we found to activate the virtualenv at your project is to link the projects directory to the virtualenv.

cd to the project's directory and link the virtualenv for example my-project-name virtualenv

This will activate the linked virtualenv every time you cd to this directory automatically From now you can use pip to install any packages you need for your project, the location of the installed packages will be at $(pyenv root)/versions/

Activating virtualenv manually for project

Catalina

You can also activate and deactivate a pyenv virtualenv manually:

Python Mac Os Catalina Version

This will alow you to use multiply versions of python or packages for the same project

List existing virtualenvs

Delete existing virtualenv

or

You and your MacOS should be ready for using python the right way without conflicting any system or Xcode Command Line Tools (used by brew)

Comments