Skip to content

Latest commit

 

History

History
95 lines (68 loc) · 4.1 KB

File metadata and controls

95 lines (68 loc) · 4.1 KB

Pyenv

Installing and switching between multiple Python versions on one machine with pyenv, without touching the system interpreter.

Overview

pyenv lets you install many Python versions side-by-side and choose which one is active globally, per-directory, or per-shell. It builds interpreters from source into ~/.pyenv, leaving the OS Python untouched. For security work this is invaluable: you can test whether a tool or payload behaves the same on 3.8 as on 3.12, or reproduce a target host's exact interpreter to validate an exploit.

Syntax

# Install pyenv (Linux) via the official installer
curl -fsSL https://pyenv.run | bash

# Add to shell init (~/.bashrc or ~/.zshrc), then restart the shell
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

Explanation

pyenv works by inserting a shims directory at the front of PATH. When you type python, the shim consults version files and dispatches to the right interpreter.

Command Purpose
pyenv install --list List all installable versions
pyenv install 3.12.4 Build and install a version
pyenv versions Show installed versions
pyenv global 3.12.4 Set the default interpreter
pyenv local 3.11.9 Pin a version for the current dir (writes .python-version)
pyenv shell 3.8.19 Set the version for the current shell session only
pyenv which python Show which interpreter a shim resolves to

Resolution precedence: shell > local (.python-version) > global.

# Install several versions and pin one to a project
pyenv install 3.11.9
pyenv install 3.12.4
cd ~/engagements/acme
pyenv local 3.11.9          # creates ./.python-version
python --version            # Python 3.11.9

Output

Python 3.11.9

Note

Building interpreters from source needs build dependencies (build-essential, libssl-dev, libffi-dev, zlib1g-dev, etc.). Missing libs cause a broken build where modules like ssl or ctypes silently fail to import.

Security Use Cases

  • Reproducing a target's exact Python version to confirm an exploit or PoC triggers before running it live.
  • Compatibility-testing a tool across 3.8 – 3.13 to guarantee it will run on whatever the engagement host provides.
  • Keeping an EOL interpreter (e.g. 3.7) isolated for analyzing legacy malware or client code without installing it system-wide.

Best Practices

  • Combine pyenv with venvs: pyenv local 3.11.9 to choose the interpreter, then python -m venv .venv for package isolation (or use pyenv-virtualenv).
  • Commit the .python-version file so teammates use the same interpreter line.
  • Install the build dependencies first so interpreters build with ssl/ctypes support.
  • Use pyenv only for versions your distro does not package; the system package is fine for the base.

Common Mistakes

  • Forgetting eval "$(pyenv init -)" in the shell rc, so the shims never take effect and python stays the system one.
  • Building without dev headers, producing an interpreter that cannot import ssl — network tools then fail cryptically.
  • Confusing pyenv version selection with package isolation — pyenv picks the interpreter; you still need a venv for dependencies.

Practical Lab

Goal: install two interpreters and switch between them.

  1. Install pyenv and its build deps, then restart the shell.
  2. pyenv install 3.11.9 && pyenv install 3.12.4.
  3. pyenv global 3.12.4; confirm python --version.
  4. cd into a project dir, run pyenv local 3.11.9, and confirm python --version now reports 3.11.9 there while the parent dir still shows 3.12.4.

References

Related

  • [[Python-Versions]]
  • [[Managing-Virtual-Environments]]
  • [[Installing-Python-on-Linux]]
  • [[Python-Environment-Setup/Readme|Python Environment Setup]] — module index
  • [[Readme|Python for Security Professionals]] — course home