Quick Answer

ModuleNotFoundError means Python could not find the module on its import path. The usual causes are installing into a different interpreter than the one running your code, forgetting to activate a virtual environment, naming your own file the same as the library you are importing, or a typo in the module name. The reliable fix is to install with python -m pip install rather than plain pip, which guarantees both refer to the same Python.

What Python Is Telling You

ModuleNotFoundError: No module named 'requests'

Python looked through every directory on its import path and did not find that module. Note it is not saying the package is uninstalled — it is saying this interpreter cannot see it.

That distinction is the whole article. Most people hit this after successfully running pip install requests, which is why it feels like the computer is lying.

You can see exactly where Python is looking:

import sys
print(sys.executable)   # which python is running
print(sys.path)         # every folder it searches for imports

Then compare with where pip installed:

pip show requests       # look at the Location line

If the Location is not inside a folder that appears in sys.path, you have found the problem — you are running one Python and installing into another.

Cause 1: pip and python Are Different Pythons

Many machines have several Python installations: one from python.org, one from the Microsoft Store, one bundled with Anaconda, and on macOS or Linux the system Python. Each has its own pip and its own packages.

Plain pip resolves to whichever appears first on your PATH, which is not necessarily the interpreter your editor or terminal runs.

The fix that always works:

python -m pip install requests

This runs pip as a module of the specific interpreter you invoked, so the package cannot land somewhere else. Make it your default habit and this cause disappears.

To confirm which is which:

where python  &&  where pip      # Windows
which python  &&  which pip      # macOS / Linux

If they live in different folders, that mismatch is your error. On systems with both Python 2 and 3 present, use python3 -m pip explicitly.

Cause 2: The Virtual Environment Is Not Active

If the project uses a virtual environment, packages installed inside it are invisible from outside — that is the entire point of one.

The symptom is code that worked yesterday failing today, because you opened a new terminal and forgot to activate.

# Check: the prompt should show the environment name
(venv) C:\projects\myapp>

# Activate
venv\Scripts\activate          # Windows
source venv/bin/activate       # macOS / Linux

No (venv) prefix means you are using the global Python, which does not have your project's packages.

The reverse also happens: the environment is active in your terminal, but your editor is running a different interpreter. In VS Code, press Ctrl+Shift+P, choose Python: Select Interpreter, and pick the one inside your project's venv folder. Otherwise the terminal works while the Run button fails, which is a genuinely confusing combination.

Jupyter has its own version of this: the kernel may point at a different environment than the terminal you installed from. import sys; print(sys.executable) inside a notebook cell tells you which one it is actually using.

Cause 3: You Named a File After the Library

This one produces bewildering errors because the import appears to work and then fails inside.

# You create random.py to practise with random numbers
import random
print(random.randint(1, 10))

# AttributeError: module 'random' has no attribute 'randint'

Python searches the current directory first. Your random.py shadows the standard library module, so import random imports your own empty file.

Common casualties: random.py, json.py, email.py, string.py, math.py, test.py, csv.py, and socket.py.

A related trap is a leftover __pycache__ folder holding the compiled version of a file you have since renamed. If a shadowing error persists after renaming, delete __pycache__.

The fix is simply to rename your file to something unambiguous — random_practice.py. To check whether shadowing is happening:

import random
print(random.__file__)   # should be inside Python's lib folder, not your project

The Remaining Causes

The install name differs from the import name. There is no rule that they match, and several popular libraries differ:

pip install opencv-python     →   import cv2
pip install pillow            →   import PIL
pip install beautifulsoup4    →   import bs4
pip install scikit-learn      →   import sklearn
pip install pyyaml            →   import yaml
pip install python-dotenv     →   import dotenv

If a fresh install still will not import, check the package's documentation for its actual import name before assuming something is broken.

Your own package structure. Importing across folders in your project fails when Python does not treat those folders as packages or when the script is run from the wrong directory. Running python -m package.module from the project root behaves more predictably than running the file directly, because it sets the import path from the root.

Case sensitivity. Linux and macOS distinguish import Requests from import requests; Windows often does not. Code that works locally then fails on a Linux server is frequently this.

Installed for a different user. Using sudo pip install or pip install --user can place packages where your interpreter is not looking. Avoid sudo pip entirely — use a virtual environment instead.

Frequently Asked Questions

I installed the package but Python still cannot find it. Why? You almost certainly installed into a different interpreter than the one running your code. Use python -m pip install instead of plain pip, which guarantees they match, and check that your virtual environment is active.
Why does my editor say the module is missing when the terminal works? The editor is running a different interpreter. In VS Code, use Python: Select Interpreter from the command palette and choose the one inside your project's venv folder.
Why does importing a standard library module fail? You likely have a file with the same name in your project — random.py, json.py or similar — which shadows the real module because Python searches the current directory first. Rename your file and delete any __pycache__ folder.
Why is the import name different from the pip name? There is no requirement that they match. opencv-python imports as cv2, pillow as PIL, beautifulsoup4 as bs4 and scikit-learn as sklearn. Check the package documentation for its import name.
Should I use sudo pip install to fix permissions errors? No. It writes into the system Python and can break operating system tooling that depends on specific versions. Create a virtual environment for the project instead, which needs no elevated permissions.