Understanding Python 2 vs 3, how to check the interpreter version, selecting a specific python3.x, and why end-of-life (EOL) matters for security tooling.
Python 2 reached end-of-life on 1 January 2020 and receives no security patches — all new work should target Python 3. Even within Python 3, minor versions (3.9, 3.11, 3.12, 3.13) differ in syntax features, standard-library modules, and support windows. A security professional must know exactly which interpreter runs a script, because a scanner or exploit PoC written for 3.11 may fail on an older target's 3.6.
python3 --version # e.g. Python 3.12.4
python3.11 --version # invoke a specific minor version
python3 -c "import sys; print(sys.version_info)"Python versioning is MAJOR.MINOR.MICRO. Compatibility is guaranteed within a minor line but not across them.
| Version | Status (2026) | Notes |
|---|---|---|
| Python 2.7 | EOL (2020) | No security fixes — avoid; only for legacy target analysis |
| Python 3.8 | EOL (2024) | Do not target new work |
| Python 3.9 – 3.12 | Security-supported | Safe range for tooling |
| Python 3.13+ | Current / bugfix | Newest features (e.g. improved REPL, JIT) |
Key Python 2 → 3 differences that break scripts:
printis a function:print("x"), notprint "x".- Strings are Unicode by default;
bytesandstrare distinct — critical when parsing network/binary data. - Integer division uses
//;/always returns a float. input()no longer evals;urllib,http, and many modules were reorganized.
import sys
# Guard a script so it refuses to run on an unsupported interpreter
if sys.version_info < (3, 9):
sys.exit("This tool requires Python 3.9 or newer.")
print(f"Running on Python {sys.version.split()[0]}")Running on Python 3.12.4
# List every python interpreter available on PATH
compgen -c | grep -E '^python[0-9.]*$' | sort -u
# Check versions of each
for p in python3.9 python3.11 python3.12; do
command -v "$p" >/dev/null && "$p" --version
donePython 3.9.18
Python 3.11.9
Python 3.12.4
- Confirming a target host's interpreter before dropping a Python payload — an exploit using f-strings (3.6+) or
matchstatements (3.10+) will crash on older builds. - Pinning a reproducible interpreter version per engagement so a scan produces identical results months later during a retest.
- Recognizing EOL interpreters on a client's assets as a finding: unsupported Python receives no CVE patches.
- Target the oldest still-supported minor version you realistically need, then test on the newest.
- Add a
sys.version_infoguard at the top of distributable tools. - Record the exact interpreter version in your engagement notes and
requirements.txt(viapython_requires). - Use [[Pyenv]] to keep multiple versions side-by-side for compatibility testing.
- Writing
pythonin scripts and shebangs — on modern distros it may be absent or ambiguous. Usepython3or a venv. - Assuming a feature exists on the target's interpreter (walrus
:=is 3.8+,matchis 3.10+,tomllibis 3.11+). - Treating Python 2 as "still fine" for quick jobs — it silently mishandles Unicode and has no security support.
Goal: detect and compare interpreters, and prove a version guard works.
- Run
python3 --versionandpython2 --version 2>/dev/null || echo "no python2". - Save the version-guard snippet above as
guard.py. - Run it with
python3 guard.py(should print the version). - If you have
pyenv, install an old version (pyenv install 3.8.19) and runguard.pywith it to see the guard triggersys.exit.
- Python 2.7 end-of-life notice
- Python release status / supported versions
- Python docs — sys.version_info
- [[Installing-Python-on-Linux]]
- [[Pyenv]]
- [[Managing-Virtual-Environments]]
- [[Python-Environment-Setup/Readme|Python Environment Setup]] — module index
- [[Readme|Python for Security Professionals]] — course home