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#install#windowsupdated 05-25-2026

Python Installation — Windows

The fastest path. Opens Windows Terminal or PowerShell as a regular user (no admin required in most setups).

powershell
winget install Python.Python.3.12

Output:

text
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

  1. Download the installer from python.org/downloads.
  2. Run the .exe.
  3. Check "Add Python to PATH" on the first screen — this is the most common pitfall.
  4. 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.

powershell
python --version
pip --version

Output:

text
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:

powershell
py -3.12 --version      # run a specific version
py -3.12 -m pip install requests
py --list               # show all installed Python versions

Output:

text
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 python to the Microsoft Store if no real Python is installed. Run where python to see what you're actually launching. If it points to WindowsApps, install via winget or python.org and it will take precedence.

Multiple Pythons — if you have several versions installed, python may resolve to an old one. Use py -3.12 or set PYTHONPATH explicitly. 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

powershell
# 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.

powershell
# 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:

text
Found Python 3.12 [9NCVDN91XZQP] Version 3.12.1500.0
Successfully installed

The Microsoft Store build registers python.exe and python3.exe aliases under %LOCALAPPDATA%\Microsoft\WindowsApps\ rather than dropping into C:\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.

powershell
# 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:

text
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 python package (always latest) and versioned packages like python312. 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.

powershell
# 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:

text
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\. Use scoop reset python312 to flip the python shim 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.

powershell
# 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:

text
pyenv 3.1.1
Installing Python-3.12.3...
Installation complete!
3.12.3

If python still resolves to the Microsoft Store stub after installing pyenv-win, open Settings → Apps → Advanced app settings → App execution aliases and toggle off both python.exe and python3.exe. Pyenv-win's shim in %USERPROFILE%\.pyenv\pyenv-win\shims must 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.

powershell
# 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:

text
Installed Python 3.12.3 in 2.81s
 + cpython-3.12.3-windows-x86_64-msvc (python.exe)

uv python install writes to %APPDATA%\uv\python\ and never edits global PATH. If you want a python shim on PATH, run uv tool update-shell; otherwise stick with uv run and 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.

powershell
# 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:

text
 -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 python but not under py --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:

ConceptWhat it isWhen it wins
py.exe (launcher)A small system-wide dispatcher installed by python.orgSwitching between many Python versions, running scripts with version shebangs
python.exe (alias)Whatever the first match on PATH happens to beDay-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.

powershell
# 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:

text
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:

VariablePurposeWhere set
PATH (system)Directories searched for executablesSystem Properties → Environment Variables → System
PATH (user)Per-user prepend, takes precedenceSystem Properties → Environment Variables → User
PYTHONPATHExtra dirs added to sys.path for module lookupUsually unset; set for special projects
PY_PYTHONDefault version for the py launchersetx PY_PYTHON 3.12
PYTHONUTF8Force UTF-8 mode for stdout/file IOsetx PYTHONUTF8 1
PIP_INDEX_URLOverride the default PyPI mirrorUseful behind a corporate proxy
powershell
# 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.

powershell
# 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:

text
LongPathsEnabled : 1

Some legacy tools still cap at 260 chars even with the flag enabled. If you hit FileNotFoundError on paths that exist, try shortening your project root — putting code at C:\dev\proj\ is generally safer than C:\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.

powershell
# 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:

text
Python 3.12.3
Linux
bash
# From WSL: call Windows Python (note .exe suffix)
python.exe --version
python.exe -c "import sys; print(sys.executable)"

Output:

text
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 .pyd extensions are all incompatible across the boundary. Create separate .venv directories 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.

powershell
# 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:

text
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.

SymptomCauseFix
python opens the Microsoft StoreStore stub is on PATH ahead of any real PythonInstall via winget; or disable the alias under Settings → Apps → App execution aliases
pip is not recognizedScripts folder missing from PATHRe-run installer, choose Modify, tick "Add to PATH"
pip install fails with error: Microsoft Visual C++ 14.0 or greater is requiredSource package needs a compilerwinget install Microsoft.VisualStudio.2022.BuildTools or use a wheel-only package
SSL: CERTIFICATE_VERIFY_FAILEDCert store missing or proxiedpython -m pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org <pkg>
error: could not find a version that satisfies the requirementBehind a corporate proxy without PIP_INDEX_URLConfigure pip.ini with the internal mirror URL
Multiple python versions, can't tell which is whichSeveral installers ranpy --list-paths and where.exe python to inspect, then uninstall the duplicates
python -m venv says No pip module foundEmbeddable distribution without ensurepipReinstall using the standard installer (not the "embeddable" zip)
Long path errors (FileNotFoundError) on deep folders260-char path limitEnable LongPathsEnabled in the registry, restart
py: No suitable Python runtime foundNo Pythons registered with the launcherReinstall 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, two python.exe files exist, both registered with the launcher. py --list will 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 see cannot be loaded because running scripts is disabled on this system, run Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser once.

Antivirus quarantining pip downloads — Some endpoint security tools sandbox newly-downloaded .exe and .dll files. If pip install succeeds but importing the package fails with DLL 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. Use py -2 and py -3.12 explicitly in every script.

Real-world recipes

Fresh dev laptop in three commands

powershell
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

powershell
# 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)

yaml
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

powershell
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

powershell
# 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

powershell
# 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.