cheat sheet
Python Installation
Install Python 3 on Windows via winget or the python.org installer. Covers PATH setup, the py launcher, and verification steps.
Python Installation — Windows
Method 1 — winget (recommended)
The fastest path. Opens Windows Terminal or PowerShell as a regular user (no admin required in most setups).
winget install Python.Python.3.12
Output:
Found Python 3.12 [Python.Python.3.12] Version 3.12.3
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Downloading https://www.python.org/ftp/python/3.12.3/python-3.12.3-amd64.exe
Successfully verified installer hash
Starting package install...
Successfully installed
To install the latest 3.13 instead:
winget install Python.Python.3.13
Method 2 — python.org installer
- Download the installer from python.org/downloads.
- Run the
.exe. - Check "Add Python to PATH" on the first screen — this is the most common pitfall.
- Click "Install Now" for defaults, or "Customize" to change the install directory.
If you forget to check "Add to PATH," you can re-run the installer, choose Modify, and check "Add Python to environment variables."
Verify the installation
Close and reopen your terminal after installation so PATH changes take effect.
python --version
pip --version
Output:
Python 3.12.3
pip 24.0 from C:\Users\Alice\AppData\Local\Programs\Python\Python312\Lib\site-packages\pip (python 3.12)
The py launcher
Windows installs py.exe — a version switcher that survives PATH problems:
py -3.12 --version # run a specific version
py -3.12 -m pip install requests
py --list # show all installed Python versions
Output:
Python 3.12.3
Installed Pythons found by C:\Windows\py.exe Launcher for Windows
-V:3.12 * C:\Users\Alice\AppData\Local\Programs\Python\Python312\python.exe
The * marks the default version used when you just run py.
Common pitfalls
Microsoft Store Python — Windows may redirect
pythonto the Microsoft Store if no real Python is installed. Runwhere pythonto see what you're actually launching. If it points toWindowsApps, install via winget or python.org and it will take precedence.
Multiple Pythons — if you have several versions installed,
pythonmay resolve to an old one. Usepy -3.12or setPYTHONPATHexplicitly. Even better: always work inside a virtual environment (see venv).
After installing, set the default in the py launcher:
setx PY_PYTHON 3.12
Next steps
# Create a virtual environment
python -m venv .venv
.venv\Scripts\Activate.ps1 # PowerShell
.venv\Scripts\activate.bat # cmd.exe
See Virtual Environments for the full guide.
Method 3 — Microsoft Store
The Microsoft Store carries an official Python.org-published build that auto-updates with the rest of your Store apps. It is sandboxed under %LOCALAPPDATA%\Microsoft\WindowsApps\ and installs without admin rights, which makes it the path of least resistance on locked-down corporate laptops. The trade-off: the Store version cannot install to a custom path, cannot be silently scripted from a fresh image, and cannot run installers that need a registered HKLM entry for shipping COM components.
# Open the Store page directly
start ms-windows-store://pdp/?productid=9NCVDN91XZQP
# Or search from PowerShell
winget search "Python 3.12" --source msstore
winget install --source msstore --id 9NCVDN91XZQP
Output:
Found Python 3.12 [9NCVDN91XZQP] Version 3.12.1500.0
Successfully installed
The Microsoft Store build registers
python.exeandpython3.exealiases under%LOCALAPPDATA%\Microsoft\WindowsApps\rather than dropping intoC:\Program Files\. This is how it sidesteps the admin prompt — but it also means the install root is hidden behind a reparse point that some old build tools cannot follow.
Method 4 — Chocolatey
Chocolatey is a community package manager that wraps the official .exe installer with a NuGet package, so choco install python is functionally the same as running the python.org installer with silent flags. Reach for it when you already use Chocolatey for the rest of your dev toolchain and want one tool for upgrades.
# Run elevated (Chocolatey itself requires admin)
choco install python --version=3.12.3 -y
# Upgrade later
choco upgrade python -y
# Install multiple side-by-side
choco install python312 -y
choco install python313 -y
Output:
Chocolatey v2.3.0
Installing the following packages:
python
By installing, you accept licenses for the packages.
Progress: Downloading python.x64 3.12.3... 100%
python.x64 v3.12.3 [Approved]
python v3.12.3 [Approved]
Chocolatey installed 1/1 packages.
Chocolatey publishes both an unversioned
pythonpackage (always latest) and versioned packages likepython312. Use the versioned ones when you need to pin in CI; use the unversioned package on developer machines.
Method 5 — Scoop
Scoop installs everything under %USERPROFILE%\scoop\ with no admin rights and no UAC prompts. It is the cleanest path for a per-user Python that does not touch system PATH directly — Scoop adds its shims folder, and the shims forward to the current bucket version.
# Install Scoop first (one-time)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
# Install Python
scoop install python
# Install a specific version from the versions bucket
scoop bucket add versions
scoop install python312
scoop install python313
# Switch between them
scoop reset python312
Output:
Installing 'python' (3.12.3) [64bit] from 'main' bucket
Running pre_install script...
Linking ~\scoop\apps\python\current => ~\scoop\apps\python\3.12.3
Creating shim for 'python'.
Creating shim for 'pip'.
'python' (3.12.3) was installed successfully!
Multiple Pythons coexist cleanly under Scoop because each lives in its own folder under
scoop\apps\. Usescoop reset python312to flip thepythonshim to a different installed version.
Method 6 — pyenv-win
pyenv-win is the Windows fork of pyenv, written in PowerShell. It manages many Python versions per user, sets a current version via a .python-version file, and never asks for admin rights. It downloads the official Windows installers (rather than building from source like Unix pyenv) so installs are fast.
# Install via the official one-liner
Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "$HOME\install-pyenv-win.ps1"
& "$HOME\install-pyenv-win.ps1"
# Reload PATH or restart your terminal, then:
pyenv --version
# List installable versions
pyenv install --list
# Install and set a default
pyenv install 3.12.3
pyenv install 3.13.0
pyenv global 3.12.3
# Pin a project to a specific version
cd C:\Users\Alice\code\my-project
pyenv local 3.13.0
type .python-version
Output:
pyenv 3.1.1
Installing Python-3.12.3...
Installation complete!
3.12.3
If
pythonstill resolves to the Microsoft Store stub after installing pyenv-win, open Settings → Apps → Advanced app settings → App execution aliases and toggle off bothpython.exeandpython3.exe. Pyenv-win's shim in%USERPROFILE%\.pyenv\pyenv-win\shimsmust appear earlier on PATH than the WindowsApps reparse point.
Method 7 — uv python install
uv downloads a statically-linked CPython tarball (from the python-build-standalone project) and unpacks it under %APPDATA%\uv\python\. No compilers, no admin, no PATH munging — and it is fast enough (2–5 seconds) that you can install Python in a CI runner without caching.
# Install uv itself (no Python required)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Install a Python
uv python install 3.12
uv python install 3.11 3.13
# List installed / discoverable interpreters
uv python list
# Pin to a project
cd C:\Users\Alice\code\my-project
uv python pin 3.12
# Use it without ever touching PATH
uv run python --version
Output:
Installed Python 3.12.3 in 2.81s
+ cpython-3.12.3-windows-x86_64-msvc (python.exe)
uv python installwrites to%APPDATA%\uv\python\and never edits global PATH. If you want apythonshim on PATH, runuv tool update-shell; otherwise stick withuv runand the version is project-scoped.
The py launcher in depth
The py launcher (py.exe) is installed system-wide by the python.org installer and lives in C:\Windows\. Its job is to read the shebang line of a script (or a command-line argument like -3.12) and dispatch to the matching Python interpreter under HKEY_CURRENT_USER\Software\Python or HKEY_LOCAL_MACHINE\Software\Python.
# List every Python the launcher can find
py --list-paths
# Pick a specific interpreter
py -3.12 -m pip list
py -3.11 -c "import sys; print(sys.executable)"
# Run a script with a shebang like `#!/usr/bin/env python3.12`
py myscript.py
# Set the default for bare `py`
setx PY_PYTHON 3.12
setx PY_PYTHON3 3.12
Output:
-V:3.13 * C:\Users\Alice\AppData\Local\Programs\Python\Python313\python.exe
-V:3.12 C:\Users\Alice\AppData\Local\Programs\Python\Python312\python.exe
-V:3.11 C:\Users\Alice\AppData\Local\Programs\Python\Python311\python.exe
The Microsoft Store Python and uv-managed Pythons are not registered with the launcher — they appear under
where pythonbut not underpy --list. This is intentional, because the launcher reads the official Windows registry keys that only the python.org installer writes.
py launcher vs python alias
Two completely different concepts that often collide on Windows:
| Concept | What it is | When it wins |
|---|---|---|
py.exe (launcher) | A small system-wide dispatcher installed by python.org | Switching between many Python versions, running scripts with version shebangs |
python.exe (alias) | Whatever the first match on PATH happens to be | Day-to-day REPL, virtual environments (which set their own python first) |
Inside a virtual environment, the active python is always the venv's copy — both py and python are bypassed because Scripts\ is prepended to PATH. Outside a venv, the rules diverge: python follows PATH order, py follows the registry.
# Outside a venv — show the difference
where.exe python
py -c "import sys; print(sys.executable)"
# Inside a venv — both should agree
.venv\Scripts\Activate.ps1
where.exe python
py -c "import sys; print(sys.executable)"
Output:
C:\Users\Alice\AppData\Local\Microsoft\WindowsApps\python.exe
C:\Users\Alice\AppData\Local\Programs\Python\Python312\python.exe
C:\Users\Alice\code\my-project\.venv\Scripts\python.exe
C:\Users\Alice\code\my-project\.venv\Scripts\python.exe
PATH and environment variables
Python on Windows touches three environment variables that you can inspect and edit:
| Variable | Purpose | Where set |
|---|---|---|
PATH (system) | Directories searched for executables | System Properties → Environment Variables → System |
PATH (user) | Per-user prepend, takes precedence | System Properties → Environment Variables → User |
PYTHONPATH | Extra dirs added to sys.path for module lookup | Usually unset; set for special projects |
PY_PYTHON | Default version for the py launcher | setx PY_PYTHON 3.12 |
PYTHONUTF8 | Force UTF-8 mode for stdout/file IO | setx PYTHONUTF8 1 |
PIP_INDEX_URL | Override the default PyPI mirror | Useful behind a corporate proxy |
# Inspect PATH order
$env:Path -split ';'
# Inspect the persistent (registry-backed) values
[Environment]::GetEnvironmentVariable('Path', 'User') -split ';'
[Environment]::GetEnvironmentVariable('Path', 'Machine') -split ';'
# Add a directory to the user PATH (persists across reboots)
$current = [Environment]::GetEnvironmentVariable('Path', 'User')
[Environment]::SetEnvironmentVariable('Path', "C:\Python312;$current", 'User')
Always restart Windows Terminal after editing PATH from the GUI. Existing terminal sessions inherit the old environment block and will not see your edits.
Long path support
Windows defaults to a 260-character path limit, which breaks badly on projects with deep node_modules-equivalent vendoring. Python 3.6+ supports long paths if the registry flag is enabled — the python.org installer offers to do this on the last screen, but winget and Store installs do not.
# Enable long paths globally (requires admin, takes effect after reboot)
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
-Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
Output:
LongPathsEnabled : 1
Some legacy tools still cap at 260 chars even with the flag enabled. If you hit
FileNotFoundErroron paths that exist, try shortening your project root — putting code atC:\dev\proj\is generally safer thanC:\Users\Alice\Documents\Visual Studio Projects\dotnet-vs-python-comparison\....
The WSL bridge
If you also do work in WSL, you can call Python from either side, but treat them as completely separate installations. WSL has its own filesystem, its own PATH, and its own set of Python interpreters — none of them shared with the Windows side.
# From Windows: call WSL Python
wsl -- python3 --version
wsl -- python3 -c "import platform; print(platform.system())"
# From Windows: open a file that WSL owns
wsl -- python3 ~/scripts/hello.py
Output:
Python 3.12.3
Linux
# From WSL: call Windows Python (note .exe suffix)
python.exe --version
python.exe -c "import sys; print(sys.executable)"
Output:
Python 3.12.3
C:\Users\Alice\AppData\Local\Programs\Python\Python312\python.exe
Don't share virtual environments between Windows and WSL. Activation scripts, line-endings, and the binary
.pydextensions are all incompatible across the boundary. Create separate.venvdirectories per side, even in the same project tree.
Verification recipes
Run these after any new install to confirm the result. Each one is a self-contained probe that exits non-zero on failure, suitable for putting in a setup script.
# Which python does PATH resolve to?
where.exe python
where.exe python3
where.exe pip
# Which interpreters does the py launcher know about?
py --list-paths
# Confirm pip is wired to the launching Python
python -m pip --version
# Confirm the venv module is present
python -m venv "$env:TEMP\probe"; Remove-Item -Recurse "$env:TEMP\probe"; "venv OK"
# Confirm SSL works (TLS cert store missing is a common breakage)
python -c "import ssl; print(ssl.OPENSSL_VERSION)"
# Confirm pip can talk to PyPI
python -m pip install --dry-run requests
Output:
C:\Users\Alice\AppData\Local\Programs\Python\Python312\python.exe
C:\Windows\py.exe
C:\Users\Alice\AppData\Local\Programs\Python\Python312\Scripts\pip.exe
-V:3.12 * C:\Users\Alice\AppData\Local\Programs\Python\Python312\python.exe
pip 24.0 from C:\Users\Alice\AppData\Local\Programs\Python\Python312\Lib\site-packages\pip (python 3.12)
venv OK
OpenSSL 3.0.13 30 Jan 2024
Would install requests-2.32.3 certifi-2024.7.4 charset-normalizer-3.3.2 idna-3.7 urllib3-2.2.2
Troubleshooting
A quick lookup for the most common Windows-specific failure modes.
| Symptom | Cause | Fix |
|---|---|---|
python opens the Microsoft Store | Store stub is on PATH ahead of any real Python | Install via winget; or disable the alias under Settings → Apps → App execution aliases |
pip is not recognized | Scripts folder missing from PATH | Re-run installer, choose Modify, tick "Add to PATH" |
pip install fails with error: Microsoft Visual C++ 14.0 or greater is required | Source package needs a compiler | winget install Microsoft.VisualStudio.2022.BuildTools or use a wheel-only package |
SSL: CERTIFICATE_VERIFY_FAILED | Cert store missing or proxied | python -m pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org <pkg> |
error: could not find a version that satisfies the requirement | Behind a corporate proxy without PIP_INDEX_URL | Configure pip.ini with the internal mirror URL |
Multiple python versions, can't tell which is which | Several installers ran | py --list-paths and where.exe python to inspect, then uninstall the duplicates |
python -m venv says No pip module found | Embeddable distribution without ensurepip | Reinstall using the standard installer (not the "embeddable" zip) |
Long path errors (FileNotFoundError) on deep folders | 260-char path limit | Enable LongPathsEnabled in the registry, restart |
py: No suitable Python runtime found | No Pythons registered with the launcher | Reinstall via python.org or winget install Python.Python.3.12 |
Common pitfalls (extended)
Mixing user-scope and machine-scope installs — A python.org installer run as admin writes to
C:\Program Files\Python312\; the same installer run as a normal user writes to%LOCALAPPDATA%\Programs\Python\Python312\. If you accidentally do both, twopython.exefiles exist, both registered with the launcher.py --listwill show the user-scope one as*because user PATH is searched first.
PowerShell execution policy — Activation scripts (
Activate.ps1) are signed and should work out of the box. If you seecannot be loaded because running scripts is disabled on this system, runSet-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUseronce.
Antivirus quarantining pip downloads — Some endpoint security tools sandbox newly-downloaded
.exeand.dllfiles. Ifpip installsucceeds but importing the package fails withDLL load failed, check your AV quarantine.
If you must support both Python 2.7 and 3.x on the same machine (legacy enterprise apps), pin them both with the py launcher and never set either as the default
python. Usepy -2andpy -3.12explicitly in every script.
Real-world recipes
Fresh dev laptop in three commands
winget install --id Python.Python.3.12 -e --silent
winget install --id Git.Git -e --silent
winget install --id Microsoft.VisualStudioCode -e --silent
Reproducible install via Chocolatey package list
# C:\bootstrap\packages.config
@"
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="python" version="3.12.3" />
<package id="git" />
<package id="vscode" />
</packages>
"@ | Set-Content C:\bootstrap\packages.config
choco install C:\bootstrap\packages.config -y
CI matrix install (GitHub Actions on Windows runners)
strategy:
matrix:
python: ['3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv python install ${{ matrix.python }}
- run: uv venv --python ${{ matrix.python }}
- run: uv pip install -e .[test]
- run: uv run pytest
Side-by-side 3.11, 3.12, 3.13 with pyenv-win
pyenv install 3.11.9
pyenv install 3.12.3
pyenv install 3.13.0
pyenv global 3.12.3 # default for new shells
pyenv local 3.13.0 # override for the current directory
py -3.11 --version
py -3.12 --version
py -3.13 --version
Uninstalling everything cleanly
# winget
winget uninstall Python.Python.3.12
# choco
choco uninstall python python312 -y
# scoop
scoop uninstall python python312
# pyenv-win — remove a single version
pyenv uninstall 3.12.3
# uv — remove all uv-managed Pythons
uv python uninstall 3.12
# Verify nothing remains on PATH
where.exe python
where.exe py
Next steps
# Create a virtual environment
python -m venv .venv
.venv\Scripts\Activate.ps1 # PowerShell
.venv\Scripts\activate.bat # cmd.exe
See Virtual Environments for the full guide and pip vs uv for the package-manager comparison.