The Python Launcher for Unix
Launch your Python interpreter the lazy/smart way!
This project is an implementation of the py
command for Unix-based platforms
(with some potential experimentation for good measure
The goal is to have py
become the cross-platform command that Python users
typically use to launch an interpreter while doing development. By having a
command that is version-agnostic when it comes to Python, it side-steps
the "what should the python
command point to?" debate by clearly specifying
that upfront (i.e. the newest version of Python that can be found). This also
unifies the suggested command to document for launching Python on both Windows
as Unix as py
has existed as the preferred
command on Windows
since 2012 with the release of Python 3.3.
Typical usage would be:
py -m venv .venv
py ... # Normal `python` usage.
This creates a virtual environment in a .venv
directory using the latest
version of Python installed. Subsequent uses of py
will then use that virtual
environment as long as it is in the current (or higher) directory; no
environment activation required (although the Python Launcher supports activated
environments as well)!
A non-goal of this project is to become the way to launch the Python interpreter all the time. If you know the exact interpreter you want to launch then you should launch it directly; same goes for when you have requirements on the type of interpreter you want (e.g. 32-bit, framework build on macOS, etc.). The Python Launcher should be viewed as a tool of convenience, not necessity.
Installation
Linux
Linuxbrew
brew install python-launcher
https://formulae.brew.sh/formula/python-launcher
Arch
yay -S python-launcher
https://aur.archlinux.org/packages/python-launcher
Fedora
sudo dnf install python-launcher
Requires Fedora 34 or higher.
https://src.fedoraproject.org/rpms/rust-python-launcher/
RISC-V
curl --location --remote-name https://github.com/brettcannon/python-launcher/releases/download/v1.0.0/python_launcher-1.0.0-riscv64gc-unknown-linux-gnu.tar.xz
- Install into, e.g.
/usr/local
:
tar --extract --strip-components 1 --directory /usr/local --file python_launcher-1.0.0-riscv64gc-unknown-linux-gnu.tar.xz
AArch64
curl --location --remote-name https://github.com/brettcannon/python-launcher/releases/download/v1.0.0/python_launcher-1.0.0-aarch64-unknown-linux-gnu.tar.xz
- Install into, e.g.
/usr/local
:
tar --extract --strip-components 1 --directory /usr/local --file python_launcher-1.0.0-aarch64-unknown-linux-gnu.tar.xz
x86-64
curl --location --remote-name https://github.com/brettcannon/python-launcher/releases/download/v1.0.0/python_launcher-1.0.0-x86_64-unknown-linux-gnu.tar.xz
- Install into, e.g.
/usr/local
:
tar --extract --strip-components 1 --directory /usr/local --file python_launcher-1.0.0-x86_64-unknown-linux-gnu.tar.xz
macOS
Homebrew
brew install python-launcher
https://formulae.brew.sh/formula/python-launcher
Apple Silicon
curl --location --remote-name https://github.com/brettcannon/python-launcher/releases/download/v1.0.0/python_launcher-1.0.0-aarch64-apple-darwin.tar.xz
- Install into, e.g.
/usr/local
:
tar --extract --strip-components 1 --directory /usr/local --file python_launcher-1.0.0-aarch64-apple-darwin.tar.xz
x86-64
curl --location --remote-name https://github.com/brettcannon/python-launcher/releases/download/v1.0.0/python_launcher-1.0.0-x86_64-apple-darwin.tar.xz
- Install into, e.g.
/usr/local
:
tar --extract --strip-components 1 --directory /usr/local --file python_launcher-1.0.0-x86_64-apple-darwin.tar.xz
NetBSD
x86-64
curl --location --remote-name https://github.com/brettcannon/python-launcher/releases/download/v1.0.0/python_launcher-1.0.0-x86_64-unknown-netbsd.tar.xz
- Install into, e.g.
/usr/local
:
tar --extract --strip-components 1 --directory /usr/local --file python_launcher-1.0.0-x86_64-unknown-netbsd.tar.xz
Any OS supporting Rust
Crates.io
cargo install python-launcher
https://crates.io/crates/python-launcher
Source
cargo install --path .
https://github.com/brettcannon/python-launcher
Documentation
The general control flow for finding the appropriate Python executable is the following (with Python 3.6, Python 3, and the newest version of Python installed as examples):
graph TD
start[py ...] --> major_minor[-3.6]
start --> major_only[-3]
start --> best[No option specified]
major_minor --> $PATH
major_only --> PY_PYTHON3
$PATH --> exec
best --> env_var{$VIRTUAL_ENV}
env_var --> venv_dir{.venv}
venv_dir --> shebang{#! ...}
venv_dir --> exec
shebang --> PY_PYTHON([$PY_PYTHON])
shebang --> PY_PYTHON3([$PY_PYTHON3])
PY_PYTHON3 --> $PATH
PY_PYTHON --> $PATH
shebang --> $PATH
env_var --> exec[Execute Python]
See the
man page
or the top section of py --help
for more details.
See the API docs for using this project to build your own custom Launcher.
FAQ
Homebrew?
Why isn't the Python Launcher finding all of my Python versions installed viaIf you have multiple installs of Python via Homebrew but
they are not all being found (as verified via py --list
), chances are Homebrew
didn't symlink an installation due to the python
symlink already being
defined. For each installation you are missing you will need to tell Homebrew to
ignore the conflict so that the version-specific python
symlink gets created.
For instance, if your Python 3.10 installation isn't being found (due to
python3.10
not existing), try running:
brew link --overwrite python@3.10
That will critically symlink the python3.10
command. It will also overwrite
what python3
points at, so you may want to run the brew link
command for the
newest version of Python you have installed last.
Starship use the Python Launcher to display the Python version?
How do I haveAdd the following to your Starship configuration file:
[python]
python_binary = ["py"]
# The following isn't necessary, but convenient.
detect_folders = [".venv"]
By using the Launcher with Starship, your prompt will tell you which Python
version will be used if you run py
. Since the Launcher supports virtual
environments, the prompt will properly reflect both what global install of
Python will be used, but also the local virtual environment.
Nushell?
How do I get a table of Python executables inpy --list | lines | split column "│" version path | str trim
Do note that the character that is being split on is not the traditional
U+007C/"Vertical Line"/pipe character (|
),
but U+2502/"Box Drawings Light Vertical" (│
).
pyenv?
How can I make the Python Launcher use my default Python version fromIf you're using pyenv to manage your Python versions, you'll want to set the version the Launcher uses to the pyenv global version.
Add this line to your .zshrc
or .bashrc
file:
export PY_PYTHON=$(pyenv exec python -c "import sys; print('.'.join(map(str, sys.version_info[:2])))")
Or this line to your ~/.config/fish/config.fish
file:
set -gx PY_PYTHON (pyenv exec python -c "import sys; print('.'.join(map(str, sys.version_info[:2])))")
Appendix
- PEP 397: Python launcher for Windows
- PEP 486: Make the Python Launcher aware of virtual environments
- Python Launcher for Windows