# pyenv-python A pyenv shim for python that's much faster than pyenv. ### Usage This `python` shim, i.e., `$CARGO_HOME/bin/python`, loads much faster than `pyenv`'s `python` shim, which is written in Bash. This helps a lot when running CLI scripts in Python, since the time is takes to run the CLI script is often less than the time it takes `pyenv` to find `python`. For example, with `starship`, `python --version` is run every time when you're in a Python directory to display the current Python version on the prompt, but if `pyenv`'s `python` shim takes ~1 sec, it makes the prompt painfully slow. Using this `python` shim, the time for `python --version` is unnoticeable. #### Fast Script Invocation For all globally install programs, like through `pip install`, `pyenv` places a shim file in `$PYENV_ROOT/shims`, which is placed in `$PATH`. This shim has to call the real script through `pyenv`, which makes every script startup very slow, adding up to 1 second to every script, even on simple `--help` commands. As a solution, `pyenv-python`'s `python` executable supports invoking scripts with no overhead. If `python` is symlinked to `script`, then when `./script` is run, it calls `python script`, where `script` should be in the same directory as the real `python`. That is, if `python` is the real `python` executable, then `./script` calls `python "$(dirname "$(which python)")"/script`. Installed `python` scripts are normally installed in the same directory as `python`, so this makes it very easy to invoke scripts with no `pyenv` overhead. This can also be done for other binaries not named `python`, such as `python2` or `python3`. ### Performance On my local computer, `$CARGO_HOME/bin/python --version` runs about 23x faster than `$PYENV_ROOT/shims/python --version`. ```console pyenv-python on  master is 📦 v0.4.0 via 🦀 v1.53.0 took 8s ❯ hyperfine '$CARGO_HOME/bin/python --version' '$PYENV_ROOT/shims/python --version' Benchmark #1: $CARGO_HOME/bin/python --version Time (mean ± σ): 11.6 ms ± 1.6 ms [User: 1.0 ms, System: 10.3 ms] Range (min … max): 10.0 ms … 19.9 ms 120 runs Benchmark #2: $PYENV_ROOT/shims/python --version Time (mean ± σ): 258.4 ms ± 6.3 ms [User: 18.5 ms, System: 213.7 ms] Range (min … max): 249.1 ms … 273.3 ms 10 runs Summary '$CARGO_HOME/bin/python --version' ran 22.19 ± 3.09 times faster than '$PYENV_ROOT/shims/python --version' ``` ### Installation It's just published to `crates.io`, so you need `cargo` from `rustup` to install it. Then `cargo install pyenv-python` will install the `python` wrapper. For this `python` to wrap the `pyenv` `python` or the system `python`, `$CARGO_HOME/bin` must be before any other `python`s in `$PATH`. This `python` wrapper also supports a few other commands. * `python --path` prints the path of the `python` or script that it will execute. * `python --dir` prints the directory of the `python` or script that it will execute, i.e. `dirname $(python --path)`. * `python --prefix` prints the prefix directory of the `python` or script that it will execute, i.e. `dirname $(python --dir)`. This is the same as what `python -c 'import sys; print(sys.prefix)'` prints. * `python --which` prints what command will be run using which python, explaining why that python. These extra commands aren't compatible with actual `python`, but they don't clash with any actual `python` commands, and they're very useful for inspection. Previously, there was a separate `python-path` executable that did what `python --path` now does, but having one executable is much simpler.