Python Imports: Why ModuleNotFoundError Keeps Happening
How Python finds the modules you import, why the folder you run from matters, and the usual causes of ModuleNotFoundError. After this, you can fix import errors by checking instead of guessing.
Course content
Sign in to save your progress.
-
Set Up Projects That Don't Break Each Other
-
Python Virtual Environments and pip: One Project, One Environment
-
Pinning Python Dependencies With requirements.txt
-
-
-
Organize Code Other People Can Read
-
Python Modules and Packages: Splitting One Big File
-
Python Imports: Why ModuleNotFoundError Keeps Happening
-
Python Classes: When a Dictionary Is No Longer Enough
-
-
-
Work With Real Files
-
Python File Handling: Open, Read, Write, and Always Use with
-
Python pathlib: Stop Building File Paths by Hand
-
Reading, Cleaning and Writing CSV Data in Python
-
-
-
Shorter Code That Still Says What It Does
-
Python Comprehensions: Lists, Sets and Dictionaries
-
When a Comprehension Should Be a Plain Loop
-
-
-
Prove It Works Before Someone Else Finds Out
-
Python Testing Basics With pytest
-
Debugging Python With print, logging and pdb
-
-
- Final Check: Python Intermediate
ModuleNotFoundError almost never means the module is missing from the world. It means Python looked in its list of folders and didn't find it there. Once you know how that list is built, most import errors take a minute to fix instead of an hour.
Skip ahead: If you know what sys.path contains, when to use python -m, and why relative imports fail in scripts, continue to "Python Classes: When a Dictionary Is No Longer Enough."
Where Python looks
When you write import something, Python checks a list of folders, in order, and uses the first match. That list is sys.path:
import sys
for folder in sys.path[:3]:
print(repr(folder))
'...'
'/usr/lib/python3...zip'
'/usr/lib/python3...'
Your folders will be different, but the order is always the same idea:
- The folder of the script you ran (or the current folder when you use
python -mor the interactive shell). - Folders from the
PYTHONPATHenvironment variable, if set. - The standard library.
site-packagesof the active Python, where pip installs things.
Two important consequences. First, the folder you run the script from matters. Second, your own files come before the standard library, which is why a file named random.py breaks import random.
Cause 1: the package is installed in a different Python
This is the most common one. You installed into one Python and run another. Check both sides:
python -c "import sys; print(sys.executable)"
python -m pip show requests
If pip show finds nothing, the package isn't in this Python. Activate the right environment, or install with python -m pip install so it goes into the Python you are running. This is the same lesson from the virtual environments lesson, and it causes most of these errors.
Cause 2: you ran the script from the wrong place
Take this project:
project/
├── shop/
│ ├── __init__.py
│ └── pricing.py
└── tools/
└── report.py
mkdir -p shop tools && touch shop/__init__.py
echo 'def add_vat(x): return round(x * 1.12, 2)' > shop/pricing.py
# tools/report.py
from shop.pricing import add_vat
print(add_vat(100))
Traceback (most recent call last):
File ".../tools/report.py", line 2, in <module>
from shop.pricing import add_vat
ModuleNotFoundError: No module named 'shop'
Running python tools/report.py puts tools/ on sys.path, not project/. Python looks for tools/shop, which doesn't exist. The fix is to run it as a module from the project folder:
touch tools/__init__.py
python3 -m tools.report
112.0
python -m tools.report puts the current folder (the project root) on sys.path and runs tools/report.py as part of the package. Note the dot instead of a slash, and no .py at the end.
⚠ Warning: The common quick fix is sys.path.append("..") at the top of the script. It works on your computer, from that folder, today. It depends on where you run the script from, so it breaks in a scheduled task, on a server, or when someone else runs it. Fix how you run it instead.
Cause 3: relative imports in a script
Inside a package, you can import a sibling module with a dot: from .pricing import add_vat. That only works when the file is loaded as part of the package:
# shop/orders.py
from .pricing import add_vat
print(add_vat(200))
python3 shop/orders.py
Traceback (most recent call last):
File ".../shop/orders.py", line 2, in <module>
from .pricing import add_vat
ImportError: attempted relative import with no known parent package
python3 -m shop.orders
224.0
Same file, different way of running it. Run directly, Python treats it as a lone script with no package. Run with -m, it knows orders lives in shop.
Cause 4: your file shadows another module
# random.py (a file you made to test something)
print("this is my random.py")
import random
print(random.randint(1, 6))
this is my random.py
Traceback (most recent call last):
File "...", line 3, in <module>
print(random.randint(1, 6))
^^^^^^^^^^^^^^
AttributeError: module 'random' has no attribute 'randint' (consider renaming '.../random.py' since it has the same name as the standard library module named 'random' and prevents importing that standard library module)
Python 3.13 and newer add the hint in brackets at the end. Older versions stop at "has no attribute", so you have to know to look for it.
Notice it is not even a ModuleNotFoundError. The import worked. It just imported the wrong file. If a standard module suddenly "has no attribute" something it obviously has, check for a file with the same name in your folder. Rename it and delete any __pycache__ folder next to it.
A checking order that works
- Read the full error.
ModuleNotFoundError,ImportErrorandAttributeErrorpoint to different causes. - Is it a third-party package? Check
sys.executableandpython -m pip show. - Is it your own code? Check where you ran from, and try
python -mfrom the project root. - Does a file in your project have the same name as the module? Rename it.
💡 Tip: When nothing makes sense, print module.__file__ right after the import, for example import random; print(random.__file__). It shows exactly which file Python loaded. That one line ends most arguments with an import error.
What happens if you skip this step
You fix import errors by trying things: reinstall, rename, add a sys.path line, restart the editor. Sometimes one of them works and you don't know why, so the same error comes back next month and you try things again. The cause is almost always one of the four above. Checking takes less time than guessing.
Your script works when you run it from its own folder but fails from a scheduled task. Which of the four causes would you check first?
About
How Python finds the modules you import, why the folder you run from matters, and the usual causes of ModuleNotFoundError. After this, you can fix import errors by checking instead of guessing.
- Duration
- 5 min
- Last update
- 09/20/2026
Comments (0)
Sign in to commentNo comments yet.