Python venv activated but which python is still the system one
Activating a virtual environment only prepends its bin folder to PATH in that one shell. If which python still shows /usr/bin/python3, the activate step never took, you opened a new terminal, or another tool is picking a different interpreter.
What “activated” is supposed to do
A venv is just a folder (often .venv) with its own python, pip and a small activate script. Running that script puts the folder’s bin (or Scripts on Windows) at the front of PATH for the current shell and usually changes the prompt to (.venv). It does not change other terminals, background jobs, or the interpreter your editor already chose.
Prove which Python is running
which python; which python3; which pip
command -v python # same idea, works in more shells
python -c "import sys; print(sys.executable)"
pip -V # shows which Python that pip belongs to
echo $VIRTUAL_ENV # set when activate worked (Unix)
echo %VIRTUAL_ENV% # Windows cmd
All three should point into the same .venv folder. If which python says /usr/bin/python3 while pip -V says .venv, or the other way round, you have a PATH / alias mismatch: installs go one place and your code runs another. Compare two pip freeze dumps in the text diff tool to see what each environment actually has.
How to activate on each platform
| Shell | Command |
|---|---|
| bash / zsh (Linux, macOS, WSL, Git Bash) | source .venv/bin/activate or . .venv/bin/activate |
| fish | source .venv/bin/activate.fish |
| Windows cmd | .venv\Scripts\activate.bat |
| Windows PowerShell | .venv\Scripts\Activate.ps1 |
| Any OS, no activate | Call it directly: .venv/bin/python app.py or .venv\Scripts\python.exe app.py |
Typing activate alone only works if that script is already on PATH. source (or .) runs the file in the current shell so the PATH change sticks; running it as a normal program starts a child shell, changes PATH there, and throws the change away when it exits.
Common reasons it “doesn’t work”
- New terminal tab: activation is per shell. Run activate again, or configure your terminal profile / direnv with an
.envrcthat runssource .venv/bin/activate. - Created with the wrong Python: always
python3 -m venv .venv(orpy -3.12 -m venv .venvon Windows). Recreate if you upgraded Python: delete the folder and make it again. - Nested or leftover venvs: an outer activate plus an inner one leaves PATH confusing.
deactivateuntilecho $VIRTUAL_ENVis empty, then activate the one you want. - VS Code / Cursor: the status-bar interpreter (or Python: Select Interpreter) overrides the terminal. Pick
.venv/bin/python. The terminal may still need activate forpipyou type by hand. - Shebang vs PATH: a script starting
#!/usr/bin/python3ignores your venv when you run./app.py. Use#!/usr/bin/env python3after activate, or runpython app.py/ the venv’s absolute path. - Windows execution policy:
Activate.ps1blocked? Useactivate.bat, or see running scripts is disabled. - Windows py launcher:
pycan ignore the active venv and pick a global install. Preferpythonafter activate, or.venv\Scripts\python.exe. - macOS Homebrew vs /usr/bin/python3: Apple’s stub and Homebrew’s
python3are different. Create the venv with the same binary you intend to run:/opt/homebrew/bin/python3 -m venv .venv. - Aliases and functions:
alias python=python3or a shell function can shadow the venv. Check withtype python/Get-Command python.
Related
Installed a package and still get No module named? The interpreter running the code isn’t the one pip wrote to: ModuleNotFoundError. On Ubuntu 24.04 / Debian 12 the reason you need a venv at all is externally-managed-environment. PowerShell blocking Activate.ps1: running scripts is disabled. · pip: Could not find a version
Questions
Why does which python still show /usr/bin after I activated?
Either activate never ran in this shell (new tab, forgot source, or ran activate as a program instead of sourcing it), or an alias/IDE interpreter is overriding PATH. Check echo $VIRTUAL_ENV and sys.executable.
What is the difference between source activate and ./activate?
source (or .) runs the script inside your current shell so PATH changes stick. Running ./activate starts a child shell, changes PATH there, and loses the change when that child exits.
How do I use a venv in VS Code or Cursor?
Command Palette → Python: Select Interpreter → pick the one under .venv. Also activate in the integrated terminal, or rely on the chosen interpreter for Run/Debug.
Do I need to activate in systemd, cron or Docker?
No. Call the venv’s python by absolute path (.venv/bin/python app.py). Activation is a convenience for interactive shells.
Published .