The Python Launcher for UNIX
An implementation of the py
command for UNIX-based platforms.
The goal is to have py
become the cross-platform command that all Python users
use when executing a Python interpreter. By having a version-agnostic command
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 is
installed). This also unifies the suggested command to document for launching
Python on both Windows as UNIX as py
which has existed as the preferred
command on Windows for
some time.
See the top of py --help
for instructions.
Search order
Please note that while searching, the search for a Python version can become more specific. This leads to a switch in the search algorithm to the one most appropriate to the specificity of the version.
py -3.6
(specific version)
- Search
PATH
forpython3.6
py -3
(loose/major version)
- Use the version found in the
PY_PYTHON3
environment variable if defined (e.g.PY_PYTHON3=3.6
) - Search
PATH
for all instances ofpython3.Y
- Find the executable with largest
Y
that earliest onPATH
py
(any/unknown version)
- Use
${VIRTUAL_ENV}/bin/python
immediately if available - If the first argument is a file path ...
- Check for a shebang
- If executable starts with
/usr/bin/python
,/usr/local/bin/python
,/usr/bin/env python
orpython
, proceed based on the version found (barepython
is consideredpython2
for backwards-compatibility)
- Use the version found in the
PY_PYTHON
environment variable if defined (e.g.PY_PYTHON=3
orPY_PYTHON=3.6
) - Search
PATH
for all instances ofpythonX.Y
- Find the executable with the largest
X.Y
earliest onPATH
TODO
NOTE: I am using this project to learn Rust, so please don't be offended if I choose to implement something myself instead of accepting a pull request that you submit. (Pull requests to do something I have already implemented in a more idiomatic fashion are very much appreciated, though.)
PEP 397: Python launcher for Windows (documentation)
Functionality
py --list
- Output column format like
pip list
(based on a Twitter poll) - Skipping
py -0
/py -0p
/py --list-paths
for simplicity
- Keep environment variable naming?
- No other Python env vars are prefixed with
PY_
(it's alwaysPYTHON
) - The
PY_PYTHON
feels redundant
- Customized commands?
- Want a better format like TOML?
- Probably want a way to override/specify things, e.g. wanting a framework build on macOS somehow
- Aliasing? E.g.
2.7-framework
for/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
? - Just provide a way to specify a specific interpreter for a specific version? E.g.
2.7
for/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
- What about implementations that don't install to e.g.
python3.7
likepypy3
?
- Aliasing? E.g.
- How should config file search work?
- Pre-defined locations?
- Walk up from current directory?
- XDG base directory specification?
- Windows support
- Registry
PATH
- Read
../pyvenv.cfg
to resolve forAny
version- Acts as a heavyweight "symlink" to the Python executable for the virtual environment
- Speeds up environment creation by not having to copy over entire Python installation (e.g.
.pyd
files)
- Provide a
pylauncher
package (it will make the pipenv developers happy 😃; might change name topyfinder
for package) - Use
OsString
/OsStr
everywhere (versus now which is wherever it's easy w/path::Path
)?- Widest compatibility for people where they have undecodable paths (which is hopefully a very small minority)
- Massive pain to make work (e.g. cannot easily convert to a
CString
)
Polish
- Provide a helpful error message based on requested version when no interpreter found
- Start using
human-panic
- Man page?
PYLAUNCH_DEBUG
?
Maintainability
- Pare down public exposure of functions
- Consider having functions take arguments instead of querying environment
(i.e. don't directly query
PATH
,VIRTUAL_ENV
to ease testability)- Can provide functions or constants to minimize typos in querying environment
- Go through functions to adjust for returning
Option
versusResult
(e.g.split_shebang(),
version_from_flag(),
choose_executable()`) - Consider dropping
nix
dependency for a straightlibc
dependency (to potentially make Debian packaging easier)