Home Tags Contact

Python Launcher For The Win(dows)

— Don Parakin — python

Running Python on Windows? Here’s how to use Python Launcher for Windows to run multiple Python versions installed on one Windows machine. And create virtual environments too.

Years ago I needed just one version of Python installed on my Windows laptop. Then two so I had a fiddly way to switch between them. Then more versions and so more fiddlier ways to switch. Finally, I needed 32-bit versions of Python for a project that needed to use ancient 32-bit ODBC drivers.

Enough of all that fiddliness! Time to find a better way.

Needs

How to run multiple versions of Python on the same machine? How to have an old script run using Python 2.7, a project run 3.4 (because it hasn’t been fully tested yet to run on a newer version of Python), another project on 3.8 (the latest), but another run the 32-bit version of 3.7 (because of reasons).

Unix-like operating systems have shebang and symbolic links. These enable satisfactory native solutions to the problem, … if you are running a Unix-like opsys.

The Windows operating system doesn’t have these. Instead, without the Launcher, the directories of the desired Python version have to be added to the PATH environment variable so that the python command is found in the desired location.

If I want to run an old Python 2.7 script, then a run newer Python 3 script, then run the 2.7 script again, I would need to update PATH between each step. That’s tiring and error prone. Most likely, I would create wrapper .bat scripts that would prepend the desired Python to PATH before invoking the .py script. One .bat for each .py. Eventually, I’d have more wraps than Snoop Dog.

“There must be a better way” – Raymond Hettinger

Candidates

Python Launcher for Windows is part of the Python for Windows install bundle from python.org. It was added in Python 3.3 (Sept, 2012) It is installed by default when you install Python (unless you unwisely deselect it). Also, it was the result of PEP-397 (started in 2011; accepted in 2012). Python PEP’s are (usually) a thoughtful peer-reviewed process from which good designs & decisions (usually) emerge.

An alternative is pyenv-win. First released in Nov, 2019 (less than 6 months ago), it claims to be a port of rbenv-win for Ruby. I didn’t download & try it but I did read its documentation (which was above average). It does more than the Launcher, like installing versions of Python for you (not necessarily desirable). But it also does less, like not handling shebangs (see below), which are nice to have. Overall, I did not see enough incremental benefit to justify the incremental costs (not money but dependency risk, cognitive load, etc). I need more to tempt me off the main highway onto the side roads and/or into the jungle.

So, Launcher it is: the official, proven, low risk, simple, bare naked solution for Windows. But I will keep an eye on pyenv-win (it’s so young).

Solution

Python Launcher for Windows is invoked by the py command, not python.

In the ideal set-up, you will not have any version of Python in your PATH environment variable for User or System. That means, when you are outside of a virtual environment, the python command won’t be available (it might launch the annoying Microsoft Store; close it quickly).

When you are outside of a virtual environment (can’t stress that enough), instead of python yada yada you’ll enter py yada yada (to use your default Python version) or py -2.7 yada yada (to use a specific version). py will set-up the environment for you and invoke the desired version of Python.

Again, when you are outside of a virtual environment, if the instructions you are following in docs or a blog say do python … you should do py … or py -2.7 … instead.

Installing Pythons

You can install multiple versions of Python. Just download ‘em and install ‘em (rtfm). When installing,

Install at least one version of Python ≥ 3.3 to get the Launcher (it wasn’t in Python versions before 3.3). Once installed, the Launcher will handle older versions, including 2.x.

After installing several versions of Python, invoke the Launcher as follows:

> py --list-paths
Installed Pythons found by py Launcher for Windows
 -3.8-64        C:\_opt\Python38\python.exe *
 -3.8-32        C:\_opt\Python38-32\python.exe
 -3.7-64        C:\_opt\Python37\python.exe
 -3.7-32        C:\_opt\Python37-32\python.exe
 -2.7-64        C:\_opt\Python27\python.exe

py --list-paths (or py -0p for short) shows the Python versions installed and their location. I’ve installed my Python versions in “C:\_opt” (because I’m weird). Yours will likely be in either “C:\Program Files” or “C:\Program Files (x86)” (unless you are also weird).

If you want the ideal set-up, check to see if you have any Python directories in your PATH environment variable. If you do, remove all of them (ain’t needed and has a chance of causing confusion).

Environments

All Python coders should know about virtual environments. Virtual environments are extremely desirable (arguably a necessity) for projects that install and use external packages. For projects that don’t use external packages, a virtual environment can be used but may be overkill.

Here are more Launcher details for three different situations:

Non-Virtual

When you are outside of an activated virtual environment, invoke different versions of Python by invoking py with optional launcher args. These examples invoke Python and enter the REPL:

You cannot request specific maintenance levels, like py -3.7.4. That’s because you should be running the latest maintenance level (for reasons). If you need to run 3.7.4, because that’s what’s in your production environment, then install 3.7.4 as the only 3.7 version of Python on your machine.

The syntax is py [launcher-args] [python-args] script [script-args]. So, after any launcher args, the rest is passed to the invoked Python version.

The Launcher will also do shebang handling (that the Windows opsys doesn’t do). Read the docs. Use this so you don’t have to remember that, for example, your (old) foobar.py script must be invoked with Python 2.7. Add the shebang as the first line of your script:

#! /usr/bin/python2.7

Now, invoke your script without any launcher args:

py foobar.py

Since there are no launcher args specifying a Python version, the Launcher will look at the first line of the script for a shebang. It finds one and uses that to select a Python version, 2.7 in this case.

The Launcher will ignore the Unix-y part /usr/bin/ of the shebang. That’s great because it means .py scripts written for Unix-like environs can be invoked unaltered on Windows (those PEP guys were thinking ahead). And vice versa: you can write .py scripts on Windows and then use them unaltered on a Unix-like machine. (Of course, you can’t do this if the .py script has any non-portable code.)

Some more examples:

Virtual for Python ≥3.3

When inside an activated virtual environment, invoke Python with the python command. That will invoke the virtual environment’s version of Python. Only use py if, for some reason, you want to invoke a different version.

How do you create a virtual environment for Python ≥3.3 (Sept, 2012)?

Easy. Python ≥3.3 includes the venv module that will do that for you. For example, let’s create some virtual environments:

mkdir my37project
py -3.7-32 -m venv my37project\venv
mkdir my38project
py -3.8 -m venv my38project\venv

This created two project folders with a virtual environment in each: one with a Python 3.7 32-bit environment and one with a 3.8. As per convention, the virtual environments were created in a “venv” folder within each project.

Looking at the last of the commands, the py -3.8 invokes the Launcher telling it to set-up and run Python 3.8 with the remaining arguments. -m venv tells Python 3.8 to invoke the venv module with the remaining arguments. my38project\venv tells venv to create a virtual environment in a directory called “venv” within the project folder.

Now, activate your new virtual environment and verify it:

cd my38project
venv\Scripts\activate
python --version

When inside an activated virtual environment, the python command is available. Only outside of the virtual environment you won’t have it (unless the Python directories for one of your installed versions somehow got added to your PATH; if so remove it).

When inside a virtual environment, the pip command is also available. You can do pip install anypackage. The packages you install will be added to only your virtual environment.

Virtual for Python ≤3.2

When inside an activated virtual environment, invoke Python with the python command. That will invoke the virtual environment’s version of Python. Only use py if, for some reason, you want to invoke a different version.

How do you create a virtual environment for Python ≤3.2?

For Python versions ≤3.2, the venv module is not available, but pip is (unless you unwisely deselected that default option during install). You need to install the virtualenv module first. Its instructions will tell you to do pip install virtualenv or maybe python -m pip install virtualenv. But you know better (right?). You want a virtual environment for a specific version of Python. Instead you’ll do:

py -2.7 -m pip install virtualenv

This will install the virtualenv module into the site-packages of Python 2.7 (but not of any other Python x.y version). That means the module is now available to Python 2.7. You can now invoke it to create Python 2.7 virtual environments.

mkdir my27project
py -2.7 -m virtualenv my27project\venv

The py -2.7 invokes the Launcher telling it to set-up and run Python 2.7 with the remaining arguments. -m virtualenv tells Python 2.7 to invoke the virtualenv module with the remaining arguments. my27project\venv tells virtualenv to create a virtual environment in a directory called “venv” within the project. By convention, we create the virtual environment in a “venv” folder.

Now, activate your new virtual environment and verify it:

cd my27project
venv\Scripts\activate
python --version

When inside an activated virtual environment, the python command is available.

Summary

You’re all set! You’ve got multiple Pythons on your Windows machine. You can run any Python version. You can run .py scripts with shebangs. You can create virtual environments for any of your Python versions.

Now go forth and code something special!