When an import fails
ModuleNotFoundError names the module Python couldn't find. Usually it's a typo, a module in another folder, or a package that isn't installed; sometimes it's a dependency of the module you asked for.
- Read
err.nameto see exactly which module is missing, and know where Python looks (sys.path) - Check whether a module can be imported with
importlib.util.find_spec - Treat a missing optional module as "not available" while re-raising when one of its own dependencies is missing
ModuleNotFoundError: No module named 'pricng' is Python saying it looked everywhere it knows and found no module with that name. Where it looks is the list sys.path: first the folder of the program you ran, then the standard library, then the installed packages. The error object's name attribute is the exact module that was missing.
The usual causes, in order: a typo; the module is in another folder (inside a package, so it needs a dotted name); the package isn't installed in the environment you're running (in a real project you'd run python -m pip install <package> in the project's virtual environment; this browser runner can only load the packages it ships with); or a file of yours shadows a standard module (a json.py in your folder is found before the real json).
Run each example to see what it prints. Running examples doesn't count toward progress.
import importlib.util from pathlib import Path Path("pricing.py").write_text("TAX_RATE = 0.07\n", encoding="utf-8") importlib.invalidate_caches() for name in ["json", "pricing", "pricng", "requests"]: print(name, importlib.util.find_spec(name) is not None)
import jsomA module can be missing because it doesn't exist, or because something it imports doesn't. Code that treats a module as optional ("use the fast exporter if it's available") must tell those apart: catch the error, compare err.name with the module you asked for, and re-raise anything else, or a broken install is silently reported as "not available".
import importlib from pathlib import Path Path("fast_export.py").write_text("import polars\n\nFORMAT = 'parquet'\n", encoding="utf-8") importlib.invalidate_caches() def optional(name): try: return importlib.import_module(name) except ModuleNotFoundError as err: if err.name != name: raise return None print(optional("pdf_export")) try: optional("fast_export") except ModuleNotFoundError as err: print("fast_export is installed but needs", err.name)
When to use it: reading any import error, writing plug-in or optional-feature code, and checking an environment before a long job. Mistakes to avoid: catching ModuleNotFoundError (or ImportError) around everything and carrying on, "fixing" a path problem by copying files around instead of importing from the package, and naming your files after standard modules.
- ModuleNotFoundError's
err.nameis the module Python couldn't find;sys.pathis where it looked. - Typos, the wrong folder, a missing install and shadowing are the usual causes.
importlib.util.find_specchecks without importing; for optional modules, compareerr.nameand re-raise anything else.- Next module: automating real tasks with command-line arguments and files.