Running Python 2 today: interpreter, pip and virtualenv
Get a working 2.7 environment, install packages with the right pip, and understand exactly what you are accepting by keeping it alive.
Getting a 2.7 interpreter
Python 2.7 reached end of life in January 2020. It receives no security fixes, no build fixes for new compilers, and no support from most libraries. You run it because something you cannot change requires it, and that is a decision with consequences.
python2 --version # 2.7.18 is the final release
python2.7 -c "import sys; print(sys.version_info)"
# containers are the cleanest way to get 2.7 today
docker run --rm -it -v "$PWD":/app -w /app python:2.7.18-slim python --version
# the last pip that supports 2.7
python2 -m pip --version| Concern | Reality in 2.7 |
|---|---|
| Security patches | None since January 2020; CVEs stay unfixed |
| TLS | Linked against an old OpenSSL in most distro builds, so modern ciphers may be unavailable |
| Build tooling | Compiling C extensions on a current toolchain often fails |
| Package index | Many projects dropped 2.7; pip install may resolve to an old release or nothing |
| Certificates | Bundled CA lists and ssl defaults are old enough to break HTTPS calls |
Isolating a legacy project
python2 -m virtualenv venv2 # note: virtualenv, not the venv module
source venv2/bin/activate
pip install --upgrade "pip<21" "setuptools<45" "wheel<0.38"
pip install -r requirements-legacy.txt
python -c "import sys; print(sys.prefix)"- Python 2 has no
venvmodule in the standard library, so you need the third-partyvirtualenvpackage. - Cap
pipbelow 21 andsetuptoolsbelow 45: newer versions dropped 2.7 support and fail in confusing ways. - Freeze the environment with
pip freeze > requirements-legacy.txtso you can rebuild it, because PyPI keeps changing underneath you.
⚠️
Never let a Python 2 interpreter handle untrusted input or make outbound TLS connections to a modern service. An unpatched interpreter plus an old OpenSSL build is a liability, and the failure mode is silent: the code runs happily and the transport is not what you assumed.
Installation problems you will hit
# a resolution failure usually means "no 2.7-compatible release exists"
pip install requests
# ERROR: Could not find a version that satisfies the requirement requests
# pin the last release that supported 2.7
pip install "requests==2.27.1"
# build a wheel on a newer machine only if the ABI matches
pip wheel --no-deps -w wheels/ "cffi==1.15.1"- Read the error precisely: it usually says no matching distribution rather than a compile failure.
- Wheels for 2.7 exist for many old versions; the package metadata has simply been updated to exclude them.
- Prefer copying a working environment (a container image or a saved wheel directory) over re-resolving packages from the index.
FAQ
Can I still install Python 2.7 from python.org?
The installers are still published, including 2.7.18, but they are unmaintained. In practice a container built from the official 2.7 image is more reproducible than installing on a modern host.
Why does pip refuse to install a package that definitely supports 2.7?
The project may have added a newer release that declares
python_requires>=3 while older 2.7-compatible releases exist. Pin the version explicitly, or install from a saved wheel.Related
The print statement and integer division Testing legacy Python 2 code before you change it
Last refreshed 2026-09-18.