The module imported, but the name you asked for isn't there yet — circular imports are the headline cause, followed by stale bytecode, shadowing a stdlib/package name, and version drift.
a.py imports from b.py while b.py imports from a.py; at the moment of import, the needed name isn't defined yet. The traceback's 'partially initialized module' wording confirms it.
Your email.py shadows stdlib, or pip installed another version elsewhere and sys.path picks it first. python -c 'import module; print(module.__file__)' names the file actually loaded.
Docs say feature X exists, your pinned package doesn't have it yet (or renamed it). pip show <pkg> plus a grep of the installed source settles it.
python -c "import <module> as m; print(m.__file__)"
# circular fix: extract shared symbols to common.py, or defer: def f(): from b import X (import at call time)
find . -name '__pycache__' -type d -exec rm -rf {} + 2>/dev/null; find . -name '*.pyc' -delete
python -c "import pkg; print(pkg.__version__)" ; grep -r "class X\|def X" $(python -c "import pkg,os; print(os.path.dirname(pkg.__file__))") | head -3
If the error mentions 'most likely due to a circular import', it's literally telling you the fix. Naming files after stdlib modules (email.py, json.py, typing.py) creates this exact error in imports far away from the culprit.
Import order differs by entry point: circular imports only fail when the cycle is entered in the wrong state. The reliable fix is breaking the cycle, not choosing a lucky entry point.
python -c 'import email; print(email.__file__)' — a path inside your project (instead of the stdlib location) is the shadow. Rename your file.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.