The error, verbatim
Jump to the fix ↓Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'humanize'
Tested on
- Python
- 3.13.16 (setup-python) and 3.12.3 (Ubuntu system)
- pip
- 26.2.1 and 24.0
- Jupyter
- nbconvert + ipykernel in a separate venv
- OS
- Ubuntu 24.04 (GitHub Actions runner)
Contents
pip install puts a package into one Python installation. import looks in the Python that’s running your code. If those are two different installations, the package is “installed” and missing at the same time.
That’s the case most of the time. I reproduced it five ways on one machine, with one more look-alike at the end:
| What happened | Result |
|---|---|
pip belonged to Python 3.13, the script ran on the system Python 3.12 |
No module named 'humanize' on 3.12, fine on 3.13 |
| Installed into a venv, ran without activating it | No module named 'httpx' |
| Installed in a terminal, imported in a Jupyter notebook | No module named 'tabulate' |
| Installed under the import name instead of the package name | Could not find a version that satisfies the requirement cv2 |
| A file in the folder had the same name as the package | AttributeError, not ModuleNotFoundError |
Step 1: compare the two Pythons
Ask both sides where they live:
python -c "import sys; print(sys.executable)"
pip --versionpip --version ends with the Python it belongs to, like (python 3.13), and the path before it shows which installation. If it isn’t the same as sys.executable, they’re two different Pythons.
The fix that always matches is to run pip through the Python you use:
python -m pip install humanizeOn Ubuntu and Debian, the system Python refuses plain pip installs with externally-managed-environment. I had to add --user --break-system-packages for that test; a venv is the cleaner way.
On Windows the same split happens between python, py and pip, plus a Microsoft Store placeholder: Python was not found, or pip not recognized covers those.
A virtual environment that isn’t active
I installed httpx with the venv’s own pip, then ran the script with plain python: No module named 'httpx'. The package was in .venv, the script ran outside it.
Activate the venv in that terminal, or call its Python directly:
source .venv/bin/activate # Windows: .venv\Scripts\activate
python your_script.pyYour editor runs code with its own selected interpreter, so point it at the venv’s Python as well.
Jupyter notebooks
A notebook runs on its kernel, which can be a different Python from your terminal. I ran pip install tabulate in a terminal, then executed a notebook whose kernel lived in another venv: ModuleNotFoundError: No module named 'tabulate'.
Install from inside the notebook with the %pip magic, which always targets the kernel’s Python:
%pip install tabulatepip may print “Note: you may need to restart the kernel to use updated packages.” In my run the import worked without a restart.
The package name isn’t the import name
Many packages install under one name and import under another. Installing the import name gave these results:
pip install … |
What happened | Install this instead |
|---|---|---|
sklearn |
failed: “The ‘sklearn’ PyPI package is deprecated, use ‘scikit-learn’” | scikit-learn |
cv2 |
Could not find a version that satisfies the requirement cv2 |
opencv-python-headless (tested) or opencv-python |
PIL |
Could not find a version that satisfies the requirement PIL |
Pillow |
yaml |
Could not find a version that satisfies the requirement yaml |
PyYAML |
bs4 |
worked: a stub that pulls in beautifulsoup4 |
beautifulsoup4 |
dotenv |
worked: a stub that pulls in python-dotenv |
python-dotenv |
Install the package name from the last column, then import as before:
python -m pip install scikit-learnA file with the same name
A script called requests.py next to your code is imported instead of the real package. It doesn’t give ModuleNotFoundError, but it’s the same “it’s installed, why doesn’t it work” feeling. Python 3.13 says so outright:
AttributeError: module 'requests' has no attribute 'get' (consider renaming '.../requests.py' if it has the same name as a library you intended to import)
Rename the file.
How this was tested
Ubuntu 24.04 on a GitHub Actions runner, October 20, 2026, with Python 3.13.16 from setup-python on the PATH and the system Python 3.12.3 at /usr/bin/python3. Packages were installed with each Python’s pip, into a venv run with and without activation, into a terminal versus a Jupyter kernel in its own venv (executed with nbconvert), and under their import names. Every message above is the real output, from the test script.
— N.K., end of entry No.083