ImportError — DedSec Project
ImportError: separate absent modules, symbols and cycles What fails and when ImportError can occur after Python locates a module but fails to import a requested symbol, loads an…
ImportError: separate absent modules, symbols and cycles
What fails and when
ImportError can occur after Python locates a module but fails to import a requested symbol, loads an incompatible compiled extension or encounters a circular import during initialization. ModuleNotFoundError is a more specific subclass used when a module cannot be found. Installing packages repeatedly will not repair a wrong symbol name or cyclic dependency.
Self-contained executable example
Save this as 012_ImportError.py and run python3 012_ImportError.py. The example checks both the error and a valid case.
import importlib
import math
assert hasattr(math, "sqrt")
try:
exec("from math import sqrt_typo")
except ImportError as exc:
assert "sqrt_typo" in str(exc)
else:
raise AssertionError("missing name imported")
assert importlib.import_module("math").sqrt(9) == 3.0
Diagnostic sequence and safe repair
Read the full import traceback and the module path, not only the final line. Check python3 -c 'import module; print(module.file)' for file-backed modules, installed API versions and exported names. If the message says partially initialized module, sketch the import dependency graph and move shared definitions to a third module. Avoid naming local files json.py, typing.py or requests.py.
Practical lab and boundary test
Create a.py importing b and b.py importing a, with each accessing an attribute before initialization. Observe the circular-import diagnostic, then refactor shared constants into common.py. Contrast the result with a simple misspelled imported symbol.
A missing export, reproduced in a disposable directory
This fixture distinguishes a module that exists from a name it does not export. It creates two local files, runs them in a fresh Python process, then adds the missing symbol. No pip install or external dependency is involved.
import sys, subprocess, tempfile
from pathlib import Path
with tempfile.TemporaryDirectory() as temp:
folder = Path(temp)
helper = folder / 'helper.py'
main = folder / 'main.py'
helper.write_text('VALUE = 3\n', encoding='utf-8')
main.write_text('from helper import MISSING\nprint(MISSING)\n', encoding='utf-8')
def run():
return subprocess.run([sys.executable, str(main)],
cwd=folder, capture_output=True, text=True)
broken = run()
assert broken.returncode != 0 and 'ImportError' in broken.stderr
helper.write_text('VALUE = 3\nMISSING = 5\n', encoding='utf-8')
fixed = run()
assert fixed.returncode == 0 and fixed.stdout.strip() == '5', fixed.stderr
How to tell the causes apart
The first run finds helper.py but cannot import MISSING. A ModuleNotFoundError instead indicates a module name could not be resolved; a partially initialized module warning suggests a cycle. For a real failure, inspect the imported module's file, its public exports and the first importing frame. Finish by creating a two-module cycle and moving shared definitions into common.py; explain why renaming or reinstalling a package would not repair that cycle.