You ran pip install pandas. You're sure you did. And yet:
Traceback (most recent call last):
File "analysis.py", line 1, in <module>
import pandas
ModuleNotFoundError: No module named 'pandas'
This is one of the most-Googled Python errors, and it almost never means what beginners think it means ("pip is broken"). It means one specific thing: the interpreter that ran your script can't see the package — which is usually a different interpreter than the one pip installed into.
Here's the checklist I use, in the order that catches the most cases fastest.
1. Find out which Python is actually running
The single most useful command in this situation:
python -c "import sys; print(sys.executable)"
Then compare it with where pip installed the package:
pip show pandas # look at the Location: line
If sys.executable says /usr/bin/python3 but pip installed into ~/venvs/myproject/..., there's your bug. You have multiple Pythons, and the wrong one is running your code.
The bulletproof fix — install with the same interpreter that runs your script:
python -m pip install pandas
Using python -m pip instead of bare pip removes an entire category of this error, because pip on your PATH can belong to a different Python than python does.
2. Is your virtual environment actually active?
Everyone forgets this at least weekly:
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows
which python # should point inside .venv
Special cases that bite people:
- IDEs run their own interpreter. VS Code and PyCharm pick an interpreter per-project — check the interpreter selector (bottom bar in VS Code) and point it at your venv.
-
Jupyter kernels are their own thing. The notebook can run a completely different environment than your terminal.
!{sys.executable} -m pip install pandasinside a cell installs into the kernel's environment, guaranteed. -
sudo pip installinstalls somewhere else. Don't. Use a venv.
3. Check for name shadowing (the sneaky one)
If the missing module is one you know is installed — or worse, part of the standard library — look at your own filenames:
myproject/
├── random.py <- congratulations, you've shadowed the stdlib
└── main.py <- 'import random' now imports YOUR file
A local file named random.py, queue.py, email.py, or test.py silently wins over the real module and produces baffling errors — sometimes ModuleNotFoundError for things the real module imports internally, sometimes AttributeError. The same happens with a folder named like a package you installed.
Quick diagnosis:
import random
print(random.__file__) # is this YOUR file? rename it.
4. Import name ≠ install name
Some packages install under one name and import under another:
| You install | You import |
|---|---|
pip install pillow |
import PIL |
pip install beautifulsoup4 |
import bs4 |
pip install opencv-python |
import cv2 |
pip install scikit-learn |
import sklearn |
pip install pyyaml |
import yaml |
If you're staring at No module named 'PIL', installing a package literally named PIL is not the fix (and may install something malicious — typosquatting on exactly this confusion is a known attack vector). Check the package's PyPI page for the correct pairing.
5. Importing your own code? It's a path problem
For your own modules, ModuleNotFoundError means the directory containing the module isn't on sys.path:
import sys
print(sys.path) # the directories Python searches, in order
The clean fixes, best first:
-
Run from the project root as a module:
python -m mypackage.maininstead ofpython mypackage/main.py— this keeps package-relative imports working. -
Install your project in editable mode:
pip install -e .with a minimalpyproject.toml. This is the grown-up solution; your package imports the same way everywhere. - As a last resort,
PYTHONPATH=. python main.py— works, but it's a workaround, not a fix.
The 30-second version
python -c "import sys; print(sys.executable)" # which Python is this?
python -m pip show PACKAGE # is it installed HERE?
python -m pip install PACKAGE # install into THIS Python
python -c "import PACKAGE; print(PACKAGE.__file__)" # shadowed by a local file?
Nine times out of ten, the story is "pip installed into Python A, the script ran under Python B." Make them the same Python and the error disappears.
Top comments (0)